Bluetooth: controller: Use new ticker feature to get offsets
Updated the 3 places in extended advertising where the ticker was previously inquired about the expiration of another ticker ID in a separate mayfly (adv_aux, adv_sync and adv_iso). It will now use the new ticker feature where another ticker IDs expiration info will be added to the callback. Channel map updates are now handled in ticker_cb and applied immediately if the ticker is not running Signed-off-by: Troels Nilsson <trnn@demant.com>
This commit is contained in:
parent
e990ab941d
commit
714d74b77b
@ -546,6 +546,7 @@ config BT_CTLR_ADV_EXT
|
||||
depends on BT_CTLR_ADV_EXT_SUPPORT
|
||||
select BT_CTLR_CHAN_SEL_2 if BT_LL_SW_SPLIT && BT_BROADCASTER
|
||||
select BT_CTLR_SCAN_REQ_NOTIFY if BT_LL_SW_SPLIT && BT_BROADCASTER
|
||||
select BT_TICKER_EXT
|
||||
default y if BT_EXT_ADV
|
||||
help
|
||||
Enable support for Bluetooth 5.0 LE Advertising Extensions in the
|
||||
|
||||
@ -833,7 +833,6 @@ config BT_TICKER_NEXT_SLOT_GET_MATCH
|
||||
|
||||
config BT_TICKER_EXT
|
||||
bool "Ticker extensions"
|
||||
depends on !BT_TICKER_LOW_LAT && !BT_TICKER_SLOT_AGNOSTIC
|
||||
default y if BT_BROADCASTER
|
||||
help
|
||||
This option enables ticker extensions such as re-scheduling of
|
||||
|
||||
@ -82,6 +82,10 @@ struct lll_adv_iso {
|
||||
uint8_t giv[8];
|
||||
struct ccm ccm_tx;
|
||||
|
||||
/* contains the offset in ticks from the adv_sync pointing to this ISO */
|
||||
uint32_t ticks_sync_pdu_offset;
|
||||
uint16_t iso_lazy;
|
||||
|
||||
uint16_t stream_handle[BT_CTLR_ADV_ISO_STREAM_MAX];
|
||||
};
|
||||
|
||||
@ -111,6 +115,10 @@ struct lll_adv_sync {
|
||||
struct pdu_adv *last_pdu;
|
||||
#endif /* CONFIG_BT_CTLR_ADV_PDU_LINK */
|
||||
|
||||
/* contains the offset in us from adv_aux pointing to this sync */
|
||||
uint32_t us_adv_sync_pdu_offset;
|
||||
uint16_t sync_lazy;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_ISO)
|
||||
struct lll_adv_iso *iso;
|
||||
uint8_t volatile iso_chm_done_req;
|
||||
|
||||
@ -12,3 +12,5 @@ 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 remainder_us, uint32_t start_us);
|
||||
|
||||
extern void ull_adv_aux_lll_auxptr_fill(struct pdu_adv *pdu, struct lll_adv *lll_adv);
|
||||
|
||||
@ -10,3 +10,5 @@ void lll_adv_iso_create_prepare(void *param);
|
||||
void lll_adv_iso_prepare(void *param);
|
||||
|
||||
extern struct lll_adv_iso_stream *ull_adv_iso_lll_stream_get(uint16_t handle);
|
||||
|
||||
extern void ull_adv_iso_lll_biginfo_fill(struct pdu_adv *pdu, struct lll_adv_sync *lll_sync);
|
||||
|
||||
@ -9,3 +9,5 @@ int lll_adv_sync_reset(void);
|
||||
void lll_adv_sync_prepare(void *param);
|
||||
|
||||
extern uint16_t ull_adv_sync_lll_handle_get(struct lll_adv_sync *lll);
|
||||
|
||||
extern void ull_adv_sync_lll_syncinfo_fill(struct pdu_adv *pdu, struct lll_adv_aux *lll_aux);
|
||||
|
||||
@ -1039,6 +1039,20 @@ static int prepare_cb(struct lll_prepare_param *p)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
||||
if (lll->aux) {
|
||||
/* fill in aux ptr in pdu */
|
||||
ull_adv_aux_lll_auxptr_fill(pdu, lll);
|
||||
|
||||
/* 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_pri_pdu_offset += 1U;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = lll_prepare_done(lll);
|
||||
LL_ASSERT(!ret);
|
||||
}
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
#include "lll_adv.h"
|
||||
#include "lll_adv_pdu.h"
|
||||
#include "lll_adv_aux.h"
|
||||
#include "lll_adv_sync.h"
|
||||
#include "lll_filter.h"
|
||||
|
||||
#include "lll_internal.h"
|
||||
@ -42,6 +43,8 @@
|
||||
#include "lll_adv_internal.h"
|
||||
#include "lll_prof_internal.h"
|
||||
|
||||
#include "ull_adv_types.h"
|
||||
|
||||
#include "hal/debug.h"
|
||||
|
||||
static int init_reset(void);
|
||||
@ -107,17 +110,16 @@ static int init_reset(void)
|
||||
|
||||
static int prepare_cb(struct lll_prepare_param *p)
|
||||
{
|
||||
struct pdu_adv_com_ext_adv *pri_com_hdr;
|
||||
struct pdu_adv_com_ext_adv *com_hdr;
|
||||
uint32_t ticks_at_event, ticks_at_start;
|
||||
struct pdu_adv *pri_pdu, *sec_pdu;
|
||||
struct pdu_adv_aux_ptr *aux_ptr;
|
||||
struct pdu_adv_ext_hdr *pri_hdr;
|
||||
struct ll_adv_aux_set *aux;
|
||||
struct pdu_adv *pdu;
|
||||
struct lll_adv_aux *lll;
|
||||
struct lll_adv *lll_adv;
|
||||
struct ull_hdr *ull;
|
||||
uint32_t remainder;
|
||||
uint32_t start_us;
|
||||
uint8_t *pri_dptr;
|
||||
uint8_t chan_idx;
|
||||
uint8_t phy_s;
|
||||
uint8_t upd;
|
||||
uint32_t aa;
|
||||
@ -125,55 +127,18 @@ static int prepare_cb(struct lll_prepare_param *p)
|
||||
DEBUG_RADIO_START_A(1);
|
||||
|
||||
lll = p->param;
|
||||
aux = HDR_LLL2ULL(lll);
|
||||
|
||||
/* FIXME: get latest only when primary PDU without Aux PDUs */
|
||||
upd = 0U;
|
||||
sec_pdu = lll_adv_aux_data_latest_get(lll, &upd);
|
||||
LL_ASSERT(sec_pdu);
|
||||
pdu = lll_adv_aux_data_latest_get(lll, &upd);
|
||||
LL_ASSERT(pdu);
|
||||
|
||||
/* Get reference to primary PDU */
|
||||
lll_adv = lll->adv;
|
||||
pri_pdu = lll_adv_data_curr_get(lll_adv);
|
||||
LL_ASSERT(pri_pdu->type == PDU_ADV_TYPE_EXT_IND);
|
||||
|
||||
/* Get reference to extended header */
|
||||
pri_com_hdr = (void *)&pri_pdu->adv_ext_ind;
|
||||
pri_hdr = (void *)pri_com_hdr->ext_hdr_adv_data;
|
||||
pri_dptr = pri_hdr->data;
|
||||
|
||||
/* NOTE: We shall be here in auxiliary PDU prepare due to
|
||||
* aux_ptr flag being set in the extended common header
|
||||
* flags. Hence, ext_hdr_len is non-zero, an explicit check
|
||||
* is not needed.
|
||||
*/
|
||||
LL_ASSERT(pri_com_hdr->ext_hdr_len);
|
||||
|
||||
/* traverse through adv_addr, if present */
|
||||
if (pri_hdr->adv_addr) {
|
||||
pri_dptr += BDADDR_SIZE;
|
||||
}
|
||||
|
||||
/* traverse through tgt_addr, if present */
|
||||
if (pri_hdr->tgt_addr) {
|
||||
pri_dptr += BDADDR_SIZE;
|
||||
}
|
||||
|
||||
/* No CTEInfo flag in primary and secondary channel PDU */
|
||||
|
||||
/* traverse through adi, if present */
|
||||
if (pri_hdr->adi) {
|
||||
pri_dptr += sizeof(struct pdu_adv_adi);
|
||||
}
|
||||
|
||||
aux_ptr = (void *)pri_dptr;
|
||||
|
||||
/* Abort if no aux_ptr filled */
|
||||
if (unlikely(!pri_hdr->aux_ptr || !PDU_ADV_AUX_PTR_OFFSET_GET(aux_ptr))) {
|
||||
radio_isr_set(lll_isr_early_abort, lll);
|
||||
radio_disable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
chan_idx = lll_chan_sel_2(lll->data_chan_counter, aux->data_chan_id,
|
||||
aux->chm[aux->chm_first].data_chan_map,
|
||||
aux->chm[aux->chm_first].data_chan_count);
|
||||
|
||||
/* Increment counter used in ULL for channel index calculation */
|
||||
lll->data_chan_counter++;
|
||||
@ -200,14 +165,17 @@ static int prepare_cb(struct lll_prepare_param *p)
|
||||
radio_crc_configure(PDU_CRC_POLYNOMIAL,
|
||||
PDU_AC_CRC_IV);
|
||||
|
||||
/* Use channel idx in aux_ptr */
|
||||
lll_chan_set(aux_ptr->chan_idx);
|
||||
/* Set the channel index */
|
||||
lll_chan_set(chan_idx);
|
||||
|
||||
/* Set the Radio Tx Packet */
|
||||
radio_pkt_tx_set(sec_pdu);
|
||||
radio_pkt_tx_set(pdu);
|
||||
|
||||
/* Get reference to extended header */
|
||||
com_hdr = (void *)&pdu->adv_ext_ind;
|
||||
|
||||
/* Switch to Rx if connectable or scannable */
|
||||
if (pri_com_hdr->adv_mode & (BT_HCI_LE_ADV_PROP_CONN |
|
||||
if (com_hdr->adv_mode & (BT_HCI_LE_ADV_PROP_CONN |
|
||||
BT_HCI_LE_ADV_PROP_SCAN)) {
|
||||
|
||||
struct pdu_adv *scan_pdu;
|
||||
@ -227,7 +195,7 @@ static int prepare_cb(struct lll_prepare_param *p)
|
||||
* into the scan response.
|
||||
*/
|
||||
memcpy(&scan_pdu->adv_ext_ind.ext_hdr.data[ADVA_OFFSET],
|
||||
&sec_pdu->adv_ext_ind.ext_hdr.data[ADVA_OFFSET],
|
||||
&pdu->adv_ext_ind.ext_hdr.data[ADVA_OFFSET],
|
||||
BDADDR_SIZE);
|
||||
}
|
||||
|
||||
@ -255,9 +223,9 @@ static int prepare_cb(struct lll_prepare_param *p)
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK)
|
||||
} else if (sec_pdu->adv_ext_ind.ext_hdr_len &&
|
||||
sec_pdu->adv_ext_ind.ext_hdr.aux_ptr) {
|
||||
lll->last_pdu = sec_pdu;
|
||||
} else if (pdu->adv_ext_ind.ext_hdr_len &&
|
||||
pdu->adv_ext_ind.ext_hdr.aux_ptr) {
|
||||
lll->last_pdu = pdu;
|
||||
|
||||
radio_isr_set(isr_tx_chain, lll);
|
||||
radio_tmr_tifs_set(EVENT_B2B_MAFS_US);
|
||||
@ -306,6 +274,12 @@ static int prepare_cb(struct lll_prepare_param *p)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
|
||||
if (pdu->adv_ext_ind.ext_hdr_len && pdu->adv_ext_ind.ext_hdr.sync_info) {
|
||||
ull_adv_sync_lll_syncinfo_fill(pdu, lll);
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
|
||||
|
||||
ret = lll_prepare_done(lll);
|
||||
LL_ASSERT(!ret);
|
||||
}
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
#include "lll_adv.h"
|
||||
#include "lll_adv_pdu.h"
|
||||
#include "lll_adv_sync.h"
|
||||
#include "lll_adv_iso.h"
|
||||
#include "lll_df_types.h"
|
||||
|
||||
#include "lll_internal.h"
|
||||
@ -247,6 +248,12 @@ static int prepare_cb(struct lll_prepare_param *p)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_ISO)
|
||||
if (lll->iso) {
|
||||
ull_adv_iso_lll_biginfo_fill(pdu, lll);
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_ISO */
|
||||
|
||||
ret = lll_prepare_done(lll);
|
||||
LL_ASSERT(!ret);
|
||||
}
|
||||
|
||||
@ -79,6 +79,7 @@ static uint16_t adv_time_get(struct pdu_adv *pdu, struct pdu_adv *pdu_scan,
|
||||
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
|
||||
uint32_t remainder, uint16_t lazy, uint8_t force,
|
||||
void *param);
|
||||
|
||||
static void ticker_update_op_cb(uint32_t status, void *param);
|
||||
|
||||
#if defined(CONFIG_BT_PERIPHERAL)
|
||||
@ -1277,15 +1278,36 @@ uint8_t ll_adv_enable(uint8_t enable)
|
||||
lll->is_hdcd = !interval && (pdu_adv->type == PDU_ADV_TYPE_DIRECT_IND);
|
||||
if (lll->is_hdcd) {
|
||||
ret_cb = TICKER_STATUS_BUSY;
|
||||
ret = ticker_start(TICKER_INSTANCE_ID_CTLR,
|
||||
#if defined(CONFIG_BT_TICKER_EXT)
|
||||
#if !defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
|
||||
ll_adv_ticker_ext[handle].ticks_slot_window = 0;
|
||||
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
|
||||
ll_adv_ticker_ext[handle].ext_timeout_func = ticker_cb;
|
||||
ll_adv_ticker_ext[handle].expire_info_id = TICKER_NULL;
|
||||
|
||||
ret = ticker_start_ext(
|
||||
#else
|
||||
ret = ticker_start(
|
||||
#endif
|
||||
TICKER_INSTANCE_ID_CTLR,
|
||||
TICKER_USER_ID_THREAD,
|
||||
(TICKER_ID_ADV_BASE + handle),
|
||||
ticks_anchor, 0,
|
||||
(adv->ull.ticks_slot + ticks_slot_overhead),
|
||||
TICKER_NULL_REMAINDER, TICKER_NULL_LAZY,
|
||||
(adv->ull.ticks_slot + ticks_slot_overhead),
|
||||
ticker_cb, adv,
|
||||
ull_ticker_status_give, (void *)&ret_cb);
|
||||
#if defined(CONFIG_BT_TICKER_EXT)
|
||||
NULL,
|
||||
#else
|
||||
ticker_cb,
|
||||
#endif /* CONFIG_BT_TICKER_EXT */
|
||||
adv,
|
||||
ull_ticker_status_give, (void *)&ret_cb
|
||||
#if defined(CONFIG_BT_TICKER_EXT)
|
||||
,
|
||||
&ll_adv_ticker_ext[handle]
|
||||
#endif /* CONFIG_BT_TICKER_EXT */
|
||||
);
|
||||
ret = ull_ticker_status_take(ret, &ret_cb);
|
||||
if (ret != TICKER_STATUS_SUCCESS) {
|
||||
goto failure_cleanup;
|
||||
@ -1467,8 +1489,24 @@ uint8_t ll_adv_enable(uint8_t enable)
|
||||
ret_cb = TICKER_STATUS_BUSY;
|
||||
|
||||
#if defined(CONFIG_BT_TICKER_EXT)
|
||||
#if !defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
|
||||
ll_adv_ticker_ext[handle].ticks_slot_window =
|
||||
ULL_ADV_RANDOM_DELAY + ticks_slot;
|
||||
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
|
||||
|
||||
ll_adv_ticker_ext[handle].ext_timeout_func = ticker_cb;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
||||
if (lll->aux) {
|
||||
uint8_t aux_handle = ull_adv_aux_handle_get(aux);
|
||||
|
||||
ll_adv_ticker_ext[handle].expire_info_id = TICKER_ID_ADV_AUX_BASE +
|
||||
aux_handle;
|
||||
} else
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
||||
{
|
||||
ll_adv_ticker_ext[handle].expire_info_id = TICKER_NULL;
|
||||
}
|
||||
|
||||
ret = ticker_start_ext(
|
||||
#else
|
||||
@ -1489,7 +1527,12 @@ uint8_t ll_adv_enable(uint8_t enable)
|
||||
TICKER_NULL_LAZY,
|
||||
#endif /* !CONFIG_BT_TICKER_LOW_LAT && !CONFIG_BT_CTLR_LOW_LAT */
|
||||
ticks_slot,
|
||||
ticker_cb, adv,
|
||||
#if defined(CONFIG_BT_TICKER_EXT)
|
||||
NULL,
|
||||
#else
|
||||
ticker_cb,
|
||||
#endif /* CONFIG_BT_TICKER_EXT */
|
||||
adv,
|
||||
ull_ticker_status_give,
|
||||
(void *)&ret_cb
|
||||
#if defined(CONFIG_BT_TICKER_EXT)
|
||||
@ -1722,6 +1765,19 @@ struct ll_adv_set *ull_adv_is_created_get(uint8_t handle)
|
||||
|
||||
return adv;
|
||||
}
|
||||
|
||||
void ull_adv_aux_created(struct ll_adv_set *adv)
|
||||
{
|
||||
if (adv->lll.aux && adv->is_enabled) {
|
||||
uint8_t aux_handle = ull_adv_aux_handle_get(HDR_LLL2ULL(adv->lll.aux));
|
||||
uint8_t handle = ull_adv_handle_get(adv);
|
||||
|
||||
ticker_update_ext(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD,
|
||||
(TICKER_ID_ADV_BASE + handle), 0, 0, 0, 0, 0, 0,
|
||||
ticker_update_op_cb, adv, 0,
|
||||
TICKER_ID_ADV_AUX_BASE + aux_handle);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
||||
|
||||
uint8_t ull_adv_data_set(struct ll_adv_set *adv, uint8_t len,
|
||||
@ -2239,7 +2295,12 @@ static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
|
||||
static memq_link_t link;
|
||||
static struct mayfly mfy = {0, 0, &link, NULL, lll_adv_prepare};
|
||||
static struct lll_prepare_param p;
|
||||
#if defined(CONFIG_BT_TICKER_EXT)
|
||||
struct ticker_ext_context *context = param;
|
||||
struct ll_adv_set *adv = context->context;
|
||||
#else
|
||||
struct ll_adv_set *adv = param;
|
||||
#endif /* CONFIG_BT_TICKER_EXT */
|
||||
uint32_t random_delay;
|
||||
struct lll_adv *lll;
|
||||
uint32_t ret;
|
||||
@ -2280,17 +2341,29 @@ static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
|
||||
p.param = lll;
|
||||
mfy.param = &p;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT) && (CONFIG_BT_CTLR_ADV_AUX_SET > 0)
|
||||
if (adv->lll.aux) {
|
||||
uint32_t ticks_to_expire;
|
||||
uint32_t other_remainder;
|
||||
|
||||
LL_ASSERT(context->other_expire_info);
|
||||
|
||||
/* Adjust ticks to expire based on remainder value */
|
||||
ticks_to_expire = context->other_expire_info->ticks_to_expire;
|
||||
other_remainder = context->other_expire_info->remainder;
|
||||
hal_ticker_remove_jitter(&ticks_to_expire, &other_remainder);
|
||||
|
||||
/* Store the ticks and remainder offset for aux ptr population in LLL */
|
||||
adv->lll.aux->ticks_pri_pdu_offset = ticks_to_expire;
|
||||
adv->lll.aux->us_pri_pdu_offset = other_remainder;
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT && (CONFIG_BT_CTLR_ADV_AUX_SET > 0) */
|
||||
|
||||
/* Kick LLL prepare */
|
||||
ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH,
|
||||
TICKER_USER_ID_LLL, 0, &mfy);
|
||||
LL_ASSERT(!ret);
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT) && (CONFIG_BT_CTLR_ADV_AUX_SET > 0)
|
||||
if (adv->lll.aux) {
|
||||
ull_adv_aux_offset_get(adv);
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT && (CONFIG_BT_CTLR_ADV_AUX_SET > 0) */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
|
||||
adv->ticks_at_expire = ticks_at_expire;
|
||||
adv->delay_at_expire = adv->delay;
|
||||
|
||||
@ -58,14 +58,16 @@ static uint32_t aux_time_get(const struct ll_adv_aux_set *aux,
|
||||
static uint32_t aux_time_min_get(const struct ll_adv_aux_set *aux);
|
||||
static uint8_t aux_time_update(struct ll_adv_aux_set *aux, struct pdu_adv *pdu,
|
||||
struct pdu_adv *pdu_scan);
|
||||
static void mfy_aux_offset_get(void *param);
|
||||
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
|
||||
uint32_t remainder, uint16_t lazy, uint8_t force,
|
||||
void *param);
|
||||
static void ticker_op_cb(uint32_t status, void *param);
|
||||
|
||||
static struct ll_adv_aux_set ll_adv_aux_pool[CONFIG_BT_CTLR_ADV_AUX_SET];
|
||||
static void *adv_aux_free;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
|
||||
static struct ticker_ext ll_adv_aux_ticker_ext[CONFIG_BT_CTLR_ADV_AUX_SET];
|
||||
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
|
||||
#endif /* (CONFIG_BT_CTLR_ADV_AUX_SET > 0) */
|
||||
|
||||
static uint16_t did_unique[PDU_ADV_SID_COUNT];
|
||||
@ -1397,6 +1399,14 @@ uint8_t ull_adv_aux_chm_update(void)
|
||||
aux->chm[chm_last].data_chan_count =
|
||||
ull_chan_map_get(aux->chm[chm_last].data_chan_map);
|
||||
aux->chm_last = chm_last;
|
||||
|
||||
if (!aux->is_started) {
|
||||
/* Ticker not started yet, apply new channel map now
|
||||
* Note that it should be safe to modify chm_first here
|
||||
* since advertising is not active
|
||||
*/
|
||||
aux->chm_first = aux->chm_last;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: Should failure due to Channel Map Update being already in
|
||||
@ -1494,6 +1504,7 @@ uint8_t ull_adv_aux_hdr_set_clear(struct ll_adv_set *adv,
|
||||
}
|
||||
|
||||
lll_aux = &aux->lll;
|
||||
ull_adv_aux_created(adv);
|
||||
|
||||
is_aux_new = 1U;
|
||||
} else {
|
||||
@ -2475,6 +2486,42 @@ uint32_t ull_adv_aux_evt_init(struct ll_adv_aux_set *aux,
|
||||
return ticks_slot_overhead;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
|
||||
static void ticker_update_op_cb(uint32_t status, void *param)
|
||||
{
|
||||
LL_ASSERT(status == TICKER_STATUS_SUCCESS ||
|
||||
param == ull_disable_mark_get());
|
||||
}
|
||||
|
||||
void ull_adv_sync_started_stopped(struct ll_adv_aux_set *aux)
|
||||
{
|
||||
if (aux->is_started) {
|
||||
struct lll_adv_sync *lll_sync = aux->lll.adv->sync;
|
||||
struct ll_adv_sync_set *sync;
|
||||
uint8_t aux_handle;
|
||||
|
||||
LL_ASSERT(lll_sync);
|
||||
|
||||
sync = HDR_LLL2ULL(lll_sync);
|
||||
aux_handle = ull_adv_aux_handle_get(aux);
|
||||
|
||||
if (sync->is_started) {
|
||||
uint8_t sync_handle = ull_adv_sync_handle_get(sync);
|
||||
|
||||
ticker_update_ext(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD,
|
||||
(TICKER_ID_ADV_AUX_BASE + aux_handle), 0, 0, 0, 0, 0, 0,
|
||||
ticker_update_op_cb, aux, 0,
|
||||
TICKER_ID_ADV_SYNC_BASE + sync_handle);
|
||||
} else {
|
||||
ticker_update_ext(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD,
|
||||
(TICKER_ID_ADV_AUX_BASE + aux_handle), 0, 0, 0, 0, 0, 0,
|
||||
ticker_update_op_cb, aux, 0,
|
||||
TICKER_NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
|
||||
|
||||
uint32_t ull_adv_aux_start(struct ll_adv_aux_set *aux, uint32_t ticks_anchor,
|
||||
uint32_t ticks_slot_overhead)
|
||||
{
|
||||
@ -2487,15 +2534,40 @@ uint32_t ull_adv_aux_start(struct ll_adv_aux_set *aux, uint32_t ticks_anchor,
|
||||
aux_handle = ull_adv_aux_handle_get(aux);
|
||||
interval_us = aux->interval * PERIODIC_INT_UNIT_US;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
|
||||
ll_adv_aux_ticker_ext[aux_handle].ext_timeout_func = ticker_cb;
|
||||
if (aux->lll.adv->sync) {
|
||||
struct ll_adv_sync_set *sync = HDR_LLL2ULL(aux->lll.adv->sync);
|
||||
uint8_t sync_handle = ull_adv_sync_handle_get(sync);
|
||||
|
||||
ll_adv_aux_ticker_ext[aux_handle].expire_info_id = TICKER_ID_ADV_SYNC_BASE +
|
||||
sync_handle;
|
||||
} else {
|
||||
ll_adv_aux_ticker_ext[aux_handle].expire_info_id = TICKER_NULL;
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
|
||||
|
||||
ret_cb = TICKER_STATUS_BUSY;
|
||||
ret = ticker_start(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD,
|
||||
ret = ticker_start_ext(
|
||||
TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD,
|
||||
(TICKER_ID_ADV_AUX_BASE + aux_handle),
|
||||
ticks_anchor, 0U,
|
||||
HAL_TICKER_US_TO_TICKS(interval_us),
|
||||
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);
|
||||
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
|
||||
NULL,
|
||||
#else
|
||||
ticker_cb,
|
||||
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
|
||||
aux,
|
||||
ull_ticker_status_give, (void *)&ret_cb,
|
||||
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
|
||||
&ll_adv_aux_ticker_ext[aux_handle]);
|
||||
#else
|
||||
NULL);
|
||||
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
|
||||
|
||||
ret = ull_ticker_status_take(ret, &ret_cb);
|
||||
|
||||
return ret;
|
||||
@ -2587,23 +2659,6 @@ uint32_t ull_adv_aux_time_get(const struct ll_adv_aux_set *aux, uint8_t pdu_len,
|
||||
return aux_time_get(aux, pdu, pdu_len, pdu_scan_len);
|
||||
}
|
||||
|
||||
void ull_adv_aux_offset_get(struct ll_adv_set *adv)
|
||||
{
|
||||
static memq_link_t link;
|
||||
static struct mayfly mfy = {0, 0, &link, NULL, mfy_aux_offset_get};
|
||||
uint32_t ret;
|
||||
|
||||
/* NOTE: Single mayfly instance is sufficient as primary channel PDUs
|
||||
* use time reservation, and this mayfly shall complete within
|
||||
* the radio event. Multiple advertising sets do not need
|
||||
* independent mayfly allocations.
|
||||
*/
|
||||
mfy.param = adv;
|
||||
ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH, TICKER_USER_ID_ULL_LOW, 1,
|
||||
&mfy);
|
||||
LL_ASSERT(!ret);
|
||||
}
|
||||
|
||||
struct pdu_adv_aux_ptr *ull_adv_aux_lll_offset_fill(struct pdu_adv *pdu,
|
||||
uint32_t ticks_offset,
|
||||
uint32_t remainder_us,
|
||||
@ -2955,97 +3010,50 @@ static uint8_t aux_time_update(struct ll_adv_aux_set *aux, struct pdu_adv *pdu,
|
||||
return BT_HCI_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
static void mfy_aux_offset_get(void *param)
|
||||
void ull_adv_aux_lll_auxptr_fill(struct pdu_adv *pdu, struct lll_adv *adv)
|
||||
{
|
||||
struct lll_adv_aux *lll_aux = adv->aux;
|
||||
struct pdu_adv_aux_ptr *aux_ptr;
|
||||
struct lll_adv_aux *lll_aux;
|
||||
struct ll_adv_aux_set *aux;
|
||||
uint32_t ticks_to_expire;
|
||||
uint8_t data_chan_count;
|
||||
uint8_t *data_chan_map;
|
||||
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;
|
||||
uint16_t chan_counter;
|
||||
uint32_t offset_us;
|
||||
uint16_t pdu_us;
|
||||
|
||||
adv = param;
|
||||
lll_aux = adv->lll.aux;
|
||||
aux = HDR_LLL2ULL(lll_aux);
|
||||
ticker_id = TICKER_ID_ADV_AUX_BASE + ull_adv_aux_handle_get(aux);
|
||||
|
||||
id = TICKER_NULL;
|
||||
ticks_to_expire = 0U;
|
||||
ticks_current = 0U;
|
||||
retry = 4U;
|
||||
do {
|
||||
uint32_t volatile ret_cb;
|
||||
uint32_t ticks_previous;
|
||||
uint32_t ret;
|
||||
bool success;
|
||||
chan_counter = lll_aux->data_chan_counter;
|
||||
|
||||
ticks_previous = ticks_current;
|
||||
|
||||
ret_cb = TICKER_STATUS_BUSY;
|
||||
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,
|
||||
TICKER_USER_ID_ULL_LOW);
|
||||
}
|
||||
}
|
||||
|
||||
success = (ret_cb == TICKER_STATUS_SUCCESS);
|
||||
LL_ASSERT(success);
|
||||
|
||||
LL_ASSERT((ticks_current == ticks_previous) || retry--);
|
||||
|
||||
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.
|
||||
/* The offset has to be at least T_MAFS microseconds from the end of packet
|
||||
* In addition, the offset recorded in the aux ptr has the same requirement and this
|
||||
* offset is in steps of 30 microseconds; So use the quantized value in check
|
||||
*/
|
||||
lll_aux->ticks_pri_pdu_offset = ticks_to_expire;
|
||||
pdu_us = PDU_AC_US(pdu->len, adv->phy_p, adv->phy_flags);
|
||||
offset_us = HAL_TICKER_TICKS_TO_US(lll_aux->ticks_pri_pdu_offset) +
|
||||
lll_aux->us_pri_pdu_offset;
|
||||
if ((offset_us/OFFS_UNIT_30_US)*OFFS_UNIT_30_US < EVENT_MAFS_US + pdu_us) {
|
||||
struct ll_adv_aux_set *aux = HDR_LLL2ULL(lll_aux);
|
||||
uint32_t interval_us;
|
||||
|
||||
/* 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_pri_pdu_offset += 1U;
|
||||
|
||||
/* Store the microsecond remainder offset for population in other
|
||||
* advertising primary channel PDUs.
|
||||
*/
|
||||
lll_aux->us_pri_pdu_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, remainder,
|
||||
0U);
|
||||
|
||||
/* Process channel map update, if any */
|
||||
if (aux->chm_first != aux->chm_last) {
|
||||
/* Use channelMapNew */
|
||||
aux->chm_first = aux->chm_last;
|
||||
/* Offset too small, point to next aux packet instead */
|
||||
interval_us = aux->interval * PERIODIC_INT_UNIT_US;
|
||||
offset_us = offset_us + interval_us;
|
||||
lll_aux->ticks_pri_pdu_offset = HAL_TICKER_US_TO_TICKS(offset_us);
|
||||
lll_aux->us_pri_pdu_offset = offset_us -
|
||||
HAL_TICKER_TICKS_TO_US(lll_aux->ticks_pri_pdu_offset);
|
||||
chan_counter++;
|
||||
}
|
||||
|
||||
/* Calculate the radio channel to use */
|
||||
/* Fill the aux offset */
|
||||
aux_ptr = ull_adv_aux_lll_offset_fill(pdu, lll_aux->ticks_pri_pdu_offset,
|
||||
lll_aux->us_pri_pdu_offset, 0U);
|
||||
|
||||
|
||||
/* Calculate and fill the radio channel to use */
|
||||
data_chan_map = aux->chm[aux->chm_first].data_chan_map;
|
||||
data_chan_count = aux->chm[aux->chm_first].data_chan_count;
|
||||
aux_ptr->chan_idx = lll_chan_sel_2(lll_aux->data_chan_counter,
|
||||
aux_ptr->chan_idx = lll_chan_sel_2(chan_counter,
|
||||
aux->data_chan_id,
|
||||
data_chan_map, data_chan_count);
|
||||
}
|
||||
@ -3057,7 +3065,12 @@ static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
|
||||
static memq_link_t link;
|
||||
static struct mayfly mfy = {0, 0, &link, NULL, lll_adv_aux_prepare};
|
||||
static struct lll_prepare_param p;
|
||||
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
|
||||
struct ticker_ext_context *context = param;
|
||||
struct ll_adv_aux_set *aux = context->context;
|
||||
#else
|
||||
struct ll_adv_aux_set *aux = param;
|
||||
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
|
||||
struct lll_adv_aux *lll;
|
||||
uint32_t ret;
|
||||
uint8_t ref;
|
||||
@ -3078,33 +3091,57 @@ static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
|
||||
p.param = lll;
|
||||
mfy.param = &p;
|
||||
|
||||
/* Kick LLL prepare */
|
||||
ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH,
|
||||
TICKER_USER_ID_LLL, 0, &mfy);
|
||||
LL_ASSERT(!ret);
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
|
||||
struct ll_adv_set *adv;
|
||||
|
||||
adv = HDR_LLL2ULL(lll->adv);
|
||||
if (adv->lll.sync) {
|
||||
struct lll_adv_sync *lll_sync = adv->lll.sync;
|
||||
struct ll_adv_sync_set *sync;
|
||||
|
||||
sync = HDR_LLL2ULL(adv->lll.sync);
|
||||
sync = HDR_LLL2ULL(adv->lll.sync);
|
||||
if (sync->is_started) {
|
||||
sync->aux_remainder = remainder;
|
||||
ull_adv_sync_offset_get(adv);
|
||||
uint32_t ticks_to_expire;
|
||||
uint32_t sync_remainder_us;
|
||||
|
||||
LL_ASSERT(context->other_expire_info);
|
||||
|
||||
/* Reduce a tick for negative remainder and return positive remainder
|
||||
* value.
|
||||
*/
|
||||
ticks_to_expire = context->other_expire_info->ticks_to_expire;
|
||||
sync_remainder_us = context->other_expire_info->remainder;
|
||||
hal_ticker_remove_jitter(&ticks_to_expire, &sync_remainder_us);
|
||||
|
||||
/* Add a tick for negative remainder and return positive remainder
|
||||
* value.
|
||||
*/
|
||||
hal_ticker_add_jitter(&ticks_to_expire, &remainder);
|
||||
|
||||
/* Store the offset in us */
|
||||
lll_sync->us_adv_sync_pdu_offset = HAL_TICKER_TICKS_TO_US(ticks_to_expire) +
|
||||
sync_remainder_us - remainder;
|
||||
|
||||
/* store the lazy value */
|
||||
lll_sync->sync_lazy = context->other_expire_info->lazy;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
|
||||
|
||||
/* Process channel map update, if any */
|
||||
if (aux->chm_first != aux->chm_last) {
|
||||
/* Use channelMapNew */
|
||||
aux->chm_first = aux->chm_last;
|
||||
}
|
||||
|
||||
/* Kick LLL prepare */
|
||||
ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH,
|
||||
TICKER_USER_ID_LLL, 0, &mfy);
|
||||
LL_ASSERT(!ret);
|
||||
|
||||
DEBUG_RADIO_PREPARE_A(1);
|
||||
}
|
||||
|
||||
static void ticker_op_cb(uint32_t status, void *param)
|
||||
{
|
||||
*((uint32_t volatile *)param) = status;
|
||||
}
|
||||
#else /* !(CONFIG_BT_CTLR_ADV_AUX_SET > 0) */
|
||||
|
||||
static int init_reset(void)
|
||||
|
||||
@ -107,9 +107,6 @@ struct ll_adv_aux_set *ull_adv_aux_get(uint8_t handle);
|
||||
uint32_t ull_adv_aux_time_get(const struct ll_adv_aux_set *aux, uint8_t pdu_len,
|
||||
uint8_t pdu_scan_len);
|
||||
|
||||
/* helper function to schedule a mayfly to get aux offset */
|
||||
void ull_adv_aux_offset_get(struct ll_adv_set *adv);
|
||||
|
||||
/* Below are BT Spec v5.2, Vol 6, Part B Section 2.3.4 Table 2.12 defined */
|
||||
#define ULL_ADV_PDU_HDR_FIELD_NONE 0
|
||||
#define ULL_ADV_PDU_HDR_FIELD_ADVA BIT(0)
|
||||
@ -165,6 +162,9 @@ void ull_adv_sync_pdu_init(struct pdu_adv *pdu, uint8_t ext_hdr_flags,
|
||||
uint8_t ull_adv_sync_pdu_cte_info_set(struct pdu_adv *pdu, const struct pdu_cte_info *cte_info);
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
||||
/* notify adv_set that an aux instance has been created for it */
|
||||
void ull_adv_aux_created(struct ll_adv_set *adv);
|
||||
|
||||
/* helper to get information whether ADI field is avaialbe in extended advertising PDU */
|
||||
static inline bool ull_adv_sync_pdu_had_adi(const struct pdu_adv *pdu)
|
||||
{
|
||||
@ -197,6 +197,13 @@ ull_adv_aux_hdr_len_fill(struct pdu_adv_com_ext_adv *com_hdr, uint8_t len)
|
||||
{
|
||||
com_hdr->ext_hdr_len = len - PDU_AC_EXT_HEADER_SIZE_MIN;
|
||||
}
|
||||
|
||||
/* notify adv_aux_set that a sync instance has been started/stopped for it */
|
||||
void ull_adv_sync_started_stopped(struct ll_adv_aux_set *aux);
|
||||
|
||||
/* notify adv_sync_set that an iso instance has been created for it */
|
||||
void ull_adv_iso_created(struct ll_adv_sync_set *sync);
|
||||
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
||||
|
||||
/* helper function to get next unique DID value */
|
||||
@ -222,6 +229,9 @@ int ull_adv_sync_reset_finalize(void);
|
||||
/* Return ll_adv_sync_set context (unconditional) */
|
||||
struct ll_adv_sync_set *ull_adv_sync_get(uint8_t handle);
|
||||
|
||||
/* Return the sync set handle given the sync set instance */
|
||||
uint16_t ull_adv_sync_handle_get(struct ll_adv_sync_set *sync);
|
||||
|
||||
/* helper function to release periodic advertising instance */
|
||||
void ull_adv_sync_release(struct ll_adv_sync_set *sync);
|
||||
|
||||
@ -276,9 +286,6 @@ void ull_adv_sync_extra_data_set_clear(void *extra_data_prev,
|
||||
uint16_t hdr_rem_fields,
|
||||
void *data);
|
||||
|
||||
/* helper function to schedule a mayfly to get sync offset */
|
||||
void ull_adv_sync_offset_get(struct ll_adv_set *adv);
|
||||
|
||||
int ull_adv_iso_init(void);
|
||||
int ull_adv_iso_reset(void);
|
||||
|
||||
@ -291,9 +298,6 @@ uint8_t ull_adv_iso_chm_update(void);
|
||||
/* helper function to cleanup after channel map update complete */
|
||||
void ull_adv_iso_chm_complete(struct node_rx_hdr *rx);
|
||||
|
||||
/* helper function to schedule a mayfly to get BIG offset */
|
||||
void ull_adv_iso_offset_get(struct ll_adv_sync_set *sync);
|
||||
|
||||
/* helper function to handle adv ISO done BIG complete events */
|
||||
void ull_adv_iso_done_complete(struct node_rx_event_done *done);
|
||||
|
||||
|
||||
@ -62,7 +62,6 @@ static uint32_t adv_iso_start(struct ll_adv_iso_set *adv_iso,
|
||||
uint32_t iso_interval_us);
|
||||
static uint8_t adv_iso_chm_update(uint8_t big_handle);
|
||||
static void adv_iso_chm_complete_commit(struct lll_adv_iso *lll_iso);
|
||||
static void mfy_iso_offset_get(void *param);
|
||||
static void pdu_big_info_chan_map_phy_set(uint8_t *chm_phy, uint8_t *chan_map,
|
||||
uint8_t phy);
|
||||
static inline struct pdu_big_info *big_info_get(struct pdu_adv *pdu);
|
||||
@ -72,7 +71,6 @@ static inline void big_info_offset_fill(struct pdu_big_info *bi,
|
||||
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
|
||||
uint32_t remainder, uint16_t lazy, uint8_t force,
|
||||
void *param);
|
||||
static void ticker_op_cb(uint32_t status, void *param);
|
||||
static void ticker_stop_op_cb(uint32_t status, void *param);
|
||||
static void adv_iso_disable(void *param);
|
||||
static void disabled_cb(void *param);
|
||||
@ -485,6 +483,9 @@ uint8_t ll_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
|
||||
/* Associate the ISO instance with a Periodic Advertising */
|
||||
lll_adv_sync->iso = lll_adv_iso;
|
||||
|
||||
/* Notify the sync instance */
|
||||
ull_adv_iso_created(HDR_LLL2ULL(lll_adv_sync));
|
||||
|
||||
/* Commit the BIGInfo in the ACAD field of Periodic Advertising */
|
||||
lll_adv_sync_data_enqueue(lll_adv_sync, ter_idx);
|
||||
|
||||
@ -709,18 +710,6 @@ uint8_t ll_adv_iso_by_hci_handle_new(uint8_t hci_handle, uint8_t *handle)
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_HCI_ADV_HANDLE_MAPPING */
|
||||
|
||||
void ull_adv_iso_offset_get(struct ll_adv_sync_set *sync)
|
||||
{
|
||||
static memq_link_t link;
|
||||
static struct mayfly mfy = {0U, 0U, &link, NULL, mfy_iso_offset_get};
|
||||
uint32_t ret;
|
||||
|
||||
mfy.param = sync;
|
||||
ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH, TICKER_USER_ID_ULL_LOW, 1,
|
||||
&mfy);
|
||||
LL_ASSERT(!ret);
|
||||
}
|
||||
|
||||
void ull_adv_iso_done_complete(struct node_rx_event_done *done)
|
||||
{
|
||||
struct ll_adv_iso_set *adv_iso;
|
||||
@ -1063,71 +1052,32 @@ static void adv_iso_chm_complete_commit(struct lll_adv_iso *lll_iso)
|
||||
lll_adv_sync_data_enqueue(lll_sync, ter_idx);
|
||||
}
|
||||
|
||||
static void mfy_iso_offset_get(void *param)
|
||||
void ull_adv_iso_lll_biginfo_fill(struct pdu_adv *pdu, struct lll_adv_sync *lll_sync)
|
||||
{
|
||||
struct lll_adv_sync *lll_sync;
|
||||
struct ll_adv_sync_set *sync;
|
||||
struct lll_adv_iso *lll_iso;
|
||||
uint32_t ticks_to_expire;
|
||||
uint16_t latency_prepare;
|
||||
struct pdu_big_info *bi;
|
||||
uint32_t ticks_current;
|
||||
uint64_t payload_count;
|
||||
struct pdu_adv *pdu;
|
||||
uint8_t ticker_id;
|
||||
uint16_t lazy;
|
||||
uint8_t retry;
|
||||
uint8_t id;
|
||||
|
||||
sync = param;
|
||||
lll_sync = &sync->lll;
|
||||
lll_iso = lll_sync->iso;
|
||||
ticker_id = TICKER_ID_ADV_ISO_BASE + lll_iso->handle;
|
||||
|
||||
id = TICKER_NULL;
|
||||
ticks_to_expire = 0U;
|
||||
ticks_current = 0U;
|
||||
retry = 4U;
|
||||
do {
|
||||
uint32_t volatile ret_cb;
|
||||
uint32_t ticks_previous;
|
||||
uint32_t ret;
|
||||
bool success;
|
||||
/* Calculate current payload count. If refcount is non-zero, we have called
|
||||
* prepare and the LLL implementation has incremented latency_prepare already.
|
||||
* In this case we need to subtract lazy + 1 from latency_prepare
|
||||
*/
|
||||
latency_prepare = lll_iso->latency_prepare;
|
||||
if (ull_ref_get(HDR_LLL2ULL(lll_iso))) {
|
||||
/* We are in post-prepare. latency_prepare is already
|
||||
* incremented by lazy + 1 for next event
|
||||
*/
|
||||
latency_prepare -= lll_iso->iso_lazy + 1;
|
||||
}
|
||||
|
||||
ticks_previous = ticks_current;
|
||||
payload_count = lll_iso->payload_count + ((latency_prepare +
|
||||
lll_iso->iso_lazy) * lll_iso->bn);
|
||||
|
||||
ret_cb = TICKER_STATUS_BUSY;
|
||||
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,
|
||||
ticker_op_cb, (void *)&ret_cb);
|
||||
if (ret == TICKER_STATUS_BUSY) {
|
||||
/* Busy wait until Ticker Job is enabled after any Radio
|
||||
* event is done using the Radio hardware. Ticker Job
|
||||
* ISR is disabled during Radio events in LOW_LAT
|
||||
* feature to avoid Radio ISR latencies.
|
||||
*/
|
||||
while (ret_cb == TICKER_STATUS_BUSY) {
|
||||
ticker_job_sched(TICKER_INSTANCE_ID_CTLR,
|
||||
TICKER_USER_ID_ULL_LOW);
|
||||
}
|
||||
}
|
||||
|
||||
success = (ret_cb == TICKER_STATUS_SUCCESS);
|
||||
LL_ASSERT(success);
|
||||
|
||||
LL_ASSERT((ticks_current == ticks_previous) || retry--);
|
||||
|
||||
LL_ASSERT(id != TICKER_NULL);
|
||||
} while (id != ticker_id);
|
||||
|
||||
payload_count = lll_iso->payload_count + ((lll_iso->latency_prepare +
|
||||
lazy) * lll_iso->bn);
|
||||
|
||||
pdu = lll_adv_sync_data_latest_peek(lll_sync);
|
||||
bi = big_info_get(pdu);
|
||||
big_info_offset_fill(bi, ticks_to_expire, 0U);
|
||||
big_info_offset_fill(bi, lll_iso->ticks_sync_pdu_offset, 0U);
|
||||
bi->payload_count_framing[0] = payload_count;
|
||||
bi->payload_count_framing[1] = payload_count >> 8;
|
||||
bi->payload_count_framing[2] = payload_count >> 16;
|
||||
@ -1243,11 +1193,6 @@ static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
|
||||
DEBUG_RADIO_PREPARE_A(1);
|
||||
}
|
||||
|
||||
static void ticker_op_cb(uint32_t status, void *param)
|
||||
{
|
||||
*((uint32_t volatile *)param) = status;
|
||||
}
|
||||
|
||||
static void ticker_stop_op_cb(uint32_t status, void *param)
|
||||
{
|
||||
static memq_link_t link;
|
||||
|
||||
@ -51,23 +51,21 @@ static int init_reset(void);
|
||||
static uint8_t adv_type_check(struct ll_adv_set *adv);
|
||||
static inline struct ll_adv_sync_set *sync_acquire(void);
|
||||
static inline void sync_release(struct ll_adv_sync_set *sync);
|
||||
static inline uint16_t sync_handle_get(struct ll_adv_sync_set *sync);
|
||||
static uint32_t sync_time_get(const struct ll_adv_sync_set *sync,
|
||||
const struct pdu_adv *pdu);
|
||||
static inline uint8_t sync_remove(struct ll_adv_sync_set *sync,
|
||||
struct ll_adv_set *adv, uint8_t enable);
|
||||
static uint8_t sync_chm_update(uint8_t handle);
|
||||
|
||||
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);
|
||||
uint32_t offs);
|
||||
#if defined(CONFIG_BT_CTLR_ADV_ISO)
|
||||
static struct ticker_ext ll_adv_sync_ticker_ext[CONFIG_BT_CTLR_ADV_SYNC_SET];
|
||||
#endif /* CONFIG_BT_CTLR_ADV_ISO */
|
||||
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
|
||||
uint32_t remainder, uint16_t lazy, uint8_t force,
|
||||
void *param);
|
||||
static void ticker_op_cb(uint32_t status, void *param);
|
||||
|
||||
static struct ll_adv_sync_set ll_adv_sync_pool[CONFIG_BT_CTLR_ADV_SYNC_SET];
|
||||
static void *adv_sync_free;
|
||||
@ -212,6 +210,26 @@ uint8_t ll_adv_sync_param_set(uint8_t handle, uint16_t interval, uint16_t flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_ISO)
|
||||
static void ticker_update_op_cb(uint32_t status, void *param)
|
||||
{
|
||||
LL_ASSERT(status == TICKER_STATUS_SUCCESS ||
|
||||
param == ull_disable_mark_get());
|
||||
}
|
||||
|
||||
void ull_adv_iso_created(struct ll_adv_sync_set *sync)
|
||||
{
|
||||
if (sync->lll.iso && sync->is_started) {
|
||||
uint8_t iso_handle = sync->lll.iso->handle;
|
||||
uint8_t handle = ull_adv_sync_handle_get(sync);
|
||||
|
||||
ticker_update_ext(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD,
|
||||
(TICKER_ID_ADV_SYNC_BASE + handle), 0, 0, 0, 0, 0, 0,
|
||||
ticker_update_op_cb, sync, 0, TICKER_ID_ADV_ISO_BASE + iso_handle);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_ISO */
|
||||
|
||||
uint8_t ll_adv_sync_ad_data_set(uint8_t handle, uint8_t op, uint8_t len,
|
||||
uint8_t const *const data)
|
||||
{
|
||||
@ -961,6 +979,9 @@ uint8_t ll_adv_sync_enable(uint8_t handle, uint8_t enable)
|
||||
}
|
||||
|
||||
aux->is_started = 1U;
|
||||
} else {
|
||||
/* notify the auxiliary set */
|
||||
ull_adv_sync_started_stopped(HDR_LLL2ULL(lll_aux));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1047,9 +1068,14 @@ struct ll_adv_sync_set *ull_adv_sync_get(uint8_t handle)
|
||||
return &ll_adv_sync_pool[handle];
|
||||
}
|
||||
|
||||
uint16_t ull_adv_sync_handle_get(struct ll_adv_sync_set *sync)
|
||||
{
|
||||
return mem_index_get(sync, ll_adv_sync_pool, sizeof(struct ll_adv_sync_set));
|
||||
}
|
||||
|
||||
uint16_t ull_adv_sync_lll_handle_get(struct lll_adv_sync *lll)
|
||||
{
|
||||
return sync_handle_get((void *)lll->hdr.parent);
|
||||
return ull_adv_sync_handle_get((void *)lll->hdr.parent);
|
||||
}
|
||||
|
||||
void ull_adv_sync_release(struct ll_adv_sync_set *sync)
|
||||
@ -1134,17 +1160,38 @@ uint32_t ull_adv_sync_start(struct ll_adv_set *adv,
|
||||
|
||||
interval_us = (uint32_t)sync->interval * PERIODIC_INT_UNIT_US;
|
||||
|
||||
sync_handle = sync_handle_get(sync);
|
||||
sync_handle = ull_adv_sync_handle_get(sync);
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_ISO)
|
||||
ll_adv_sync_ticker_ext[sync_handle].ext_timeout_func = ticker_cb;
|
||||
if (sync->lll.iso) {
|
||||
ll_adv_sync_ticker_ext[sync_handle].expire_info_id =
|
||||
TICKER_ID_ADV_ISO_BASE + sync->lll.iso->handle;
|
||||
} else {
|
||||
ll_adv_sync_ticker_ext[sync_handle].expire_info_id = TICKER_NULL;
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_ISO */
|
||||
|
||||
ret_cb = TICKER_STATUS_BUSY;
|
||||
ret = ticker_start(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD,
|
||||
ret = ticker_start_ext(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD,
|
||||
(TICKER_ID_ADV_SYNC_BASE + sync_handle),
|
||||
ticks_anchor, 0U,
|
||||
HAL_TICKER_US_TO_TICKS(interval_us),
|
||||
HAL_TICKER_REMAINDER(interval_us), TICKER_NULL_LAZY,
|
||||
(sync->ull.ticks_slot + ticks_slot_overhead),
|
||||
ticker_cb, sync,
|
||||
ull_ticker_status_give, (void *)&ret_cb);
|
||||
#if defined(CONFIG_BT_CTLR_ADV_ISO)
|
||||
NULL,
|
||||
#else
|
||||
ticker_cb,
|
||||
#endif /* CONFIG_BT_CTLR_ADV_ISO */
|
||||
sync,
|
||||
ull_ticker_status_give, (void *)&ret_cb,
|
||||
#if defined(CONFIG_BT_CTLR_ADV_ISO)
|
||||
&ll_adv_sync_ticker_ext[sync_handle]
|
||||
#else
|
||||
NULL
|
||||
#endif /* CONFIG_BT_CTLR_ADV_ISO */
|
||||
);
|
||||
ret = ull_ticker_status_take(ret, &ret_cb);
|
||||
|
||||
return ret;
|
||||
@ -1175,7 +1222,7 @@ uint8_t ull_adv_sync_time_update(struct ll_adv_sync_set *sync,
|
||||
ret_cb = TICKER_STATUS_BUSY;
|
||||
ret = ticker_update(TICKER_INSTANCE_ID_CTLR,
|
||||
TICKER_USER_ID_THREAD,
|
||||
(TICKER_ID_ADV_SYNC_BASE + sync_handle_get(sync)),
|
||||
(TICKER_ID_ADV_SYNC_BASE + ull_adv_sync_handle_get(sync)),
|
||||
0, 0, ticks_plus, ticks_minus, 0, 0,
|
||||
ull_ticker_status_give, (void *)&ret_cb);
|
||||
ret = ull_ticker_status_take(ret, &ret_cb);
|
||||
@ -1316,18 +1363,6 @@ void ull_adv_sync_info_fill(struct ll_adv_sync_set *sync,
|
||||
si->evt_cntr = 0U;
|
||||
}
|
||||
|
||||
void ull_adv_sync_offset_get(struct ll_adv_set *adv)
|
||||
{
|
||||
static memq_link_t link;
|
||||
static struct mayfly mfy = {0, 0, &link, NULL, mfy_sync_offset_get};
|
||||
uint32_t ret;
|
||||
|
||||
mfy.param = adv;
|
||||
ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH, TICKER_USER_ID_ULL_LOW, 1,
|
||||
&mfy);
|
||||
LL_ASSERT(!ret);
|
||||
}
|
||||
|
||||
void ull_adv_sync_pdu_init(struct pdu_adv *pdu, uint8_t ext_hdr_flags,
|
||||
uint8_t phy_s, uint8_t phy_flags,
|
||||
struct pdu_cte_info *cte_info)
|
||||
@ -1924,12 +1959,6 @@ static inline void sync_release(struct ll_adv_sync_set *sync)
|
||||
mem_release(sync, &adv_sync_free);
|
||||
}
|
||||
|
||||
static inline uint16_t sync_handle_get(struct ll_adv_sync_set *sync)
|
||||
{
|
||||
return mem_index_get(sync, ll_adv_sync_pool,
|
||||
sizeof(struct ll_adv_sync_set));
|
||||
}
|
||||
|
||||
static uint32_t sync_time_get(const struct ll_adv_sync_set *sync,
|
||||
const struct pdu_adv *pdu)
|
||||
{
|
||||
@ -1952,7 +1981,7 @@ static uint8_t sync_stop(struct ll_adv_sync_set *sync)
|
||||
uint8_t sync_handle;
|
||||
int err;
|
||||
|
||||
sync_handle = sync_handle_get(sync);
|
||||
sync_handle = ull_adv_sync_handle_get(sync);
|
||||
|
||||
err = ull_ticker_stop_with_mark(TICKER_ID_ADV_SYNC_BASE + sync_handle,
|
||||
sync, &sync->lll);
|
||||
@ -1992,6 +2021,11 @@ static inline uint8_t sync_remove(struct ll_adv_sync_set *sync,
|
||||
}
|
||||
|
||||
sync->is_started = 0U;
|
||||
|
||||
if (adv->lll.aux) {
|
||||
/* notify the auxiliary set */
|
||||
ull_adv_sync_started_stopped(HDR_LLL2ULL(adv->lll.aux));
|
||||
}
|
||||
}
|
||||
|
||||
if (!enable) {
|
||||
@ -2007,6 +2041,7 @@ static uint8_t sync_chm_update(uint8_t handle)
|
||||
ULL_ADV_HDR_DATA_ACAD_PTR_SIZE];
|
||||
struct pdu_adv_sync_chm_upd_ind *chm_upd_ind;
|
||||
struct lll_adv_sync *lll_sync;
|
||||
struct ll_adv_sync_set *sync;
|
||||
struct pdu_adv *pdu_prev;
|
||||
struct ll_adv_set *adv;
|
||||
uint8_t acad_len_prev;
|
||||
@ -2090,92 +2125,37 @@ static uint8_t sync_chm_update(uint8_t handle)
|
||||
ull_chan_map_get(lll_sync->chm[chm_last].data_chan_map);
|
||||
lll_sync->chm_instant = instant;
|
||||
|
||||
/* Commit the Channel Map Indication in the ACAD field of Periodic
|
||||
* Advertising
|
||||
*/
|
||||
lll_adv_sync_data_enqueue(lll_sync, ter_idx);
|
||||
sync = HDR_LLL2ULL(lll_sync);
|
||||
if (sync->is_started) {
|
||||
/* Commit the Channel Map Indication in the ACAD field of Periodic
|
||||
* Advertising
|
||||
*/
|
||||
lll_adv_sync_data_enqueue(lll_sync, ter_idx);
|
||||
}
|
||||
|
||||
/* Initiate the Channel Map Indication */
|
||||
lll_sync->chm_last = chm_last;
|
||||
|
||||
if (!sync->is_started) {
|
||||
/* Sync not started yet, apply new channel map now */
|
||||
lll_sync->chm_first = lll_sync->chm_last;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mfy_sync_offset_get(void *param)
|
||||
void ull_adv_sync_lll_syncinfo_fill(struct pdu_adv *pdu, struct lll_adv_aux *lll_aux)
|
||||
{
|
||||
struct ll_adv_set *adv = 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;
|
||||
uint8_t retry;
|
||||
uint8_t id;
|
||||
|
||||
lll_sync = adv->lll.sync;
|
||||
sync = HDR_LLL2ULL(lll_sync);
|
||||
ticker_id = TICKER_ID_ADV_SYNC_BASE + sync_handle_get(sync);
|
||||
lll_sync = lll_aux->adv->sync;
|
||||
|
||||
id = TICKER_NULL;
|
||||
ticks_to_expire = 0U;
|
||||
ticks_current = 0U;
|
||||
retry = 4U;
|
||||
do {
|
||||
uint32_t volatile ret_cb;
|
||||
uint32_t ticks_previous;
|
||||
uint32_t ret;
|
||||
bool success;
|
||||
|
||||
ticks_previous = ticks_current;
|
||||
|
||||
ret_cb = TICKER_STATUS_BUSY;
|
||||
ret = ticker_next_slot_get_ext(TICKER_INSTANCE_ID_CTLR,
|
||||
TICKER_USER_ID_ULL_LOW,
|
||||
&id, &ticks_current,
|
||||
&ticks_to_expire, &remainder,
|
||||
&lazy, 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,
|
||||
TICKER_USER_ID_ULL_LOW);
|
||||
}
|
||||
}
|
||||
|
||||
success = (ret_cb == TICKER_STATUS_SUCCESS);
|
||||
LL_ASSERT(success);
|
||||
|
||||
LL_ASSERT((ticks_current == ticks_previous) || retry--);
|
||||
|
||||
LL_ASSERT(id != TICKER_NULL);
|
||||
} while (id != ticker_id);
|
||||
|
||||
/* Reduced a tick for negative remainder and return positive remainder
|
||||
* value.
|
||||
*/
|
||||
hal_ticker_remove_jitter(&ticks_to_expire, &remainder);
|
||||
sync_remainder_us = remainder;
|
||||
|
||||
/* Add a tick for negative remainder and return positive remainder
|
||||
* value.
|
||||
*/
|
||||
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, sync_remainder_us,
|
||||
aux_remainder_us);
|
||||
sync_info_offset_fill(si, lll_sync->us_adv_sync_pdu_offset);
|
||||
si->evt_cntr = lll_sync->event_counter + lll_sync->latency_prepare +
|
||||
lazy;
|
||||
lll_sync->sync_lazy;
|
||||
|
||||
/* Fill the correct channel map to use if at or past the instant */
|
||||
if (lll_sync->chm_first != lll_sync->chm_last) {
|
||||
@ -2238,14 +2218,8 @@ 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)
|
||||
{
|
||||
uint32_t offs;
|
||||
|
||||
offs = HAL_TICKER_TICKS_TO_US(ticks_offset) + remainder_us - start_us;
|
||||
|
||||
if (offs >= OFFS_ADJUST_US) {
|
||||
offs -= OFFS_ADJUST_US;
|
||||
si->offs_adjust = 1U;
|
||||
@ -2269,7 +2243,12 @@ static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
|
||||
static memq_link_t link;
|
||||
static struct mayfly mfy = {0, 0, &link, NULL, lll_adv_sync_prepare};
|
||||
static struct lll_prepare_param p;
|
||||
#if defined(CONFIG_BT_CTLR_ADV_ISO)
|
||||
struct ticker_ext_context *context = param;
|
||||
struct ll_adv_sync_set *sync = context->context;
|
||||
#else
|
||||
struct ll_adv_sync_set *sync = param;
|
||||
#endif /* CONFIG_BT_CTLR_ADV_ISO */
|
||||
struct lll_adv_sync *lll;
|
||||
uint32_t ret;
|
||||
uint8_t ref;
|
||||
@ -2290,21 +2269,22 @@ static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
|
||||
p.param = lll;
|
||||
mfy.param = &p;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_ISO)
|
||||
if (lll->iso) {
|
||||
struct lll_adv_iso *lll_iso = lll->iso;
|
||||
|
||||
LL_ASSERT(context->other_expire_info);
|
||||
|
||||
/* Check: No need for remainder in this case? */
|
||||
lll_iso->ticks_sync_pdu_offset = context->other_expire_info->ticks_to_expire;
|
||||
lll_iso->iso_lazy = context->other_expire_info->lazy;
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_ISO */
|
||||
|
||||
/* Kick LLL prepare */
|
||||
ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH,
|
||||
TICKER_USER_ID_LLL, 0, &mfy);
|
||||
LL_ASSERT(!ret);
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_ISO)
|
||||
if (lll->iso) {
|
||||
ull_adv_iso_offset_get(sync);
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_ISO */
|
||||
|
||||
DEBUG_RADIO_PREPARE_A(1);
|
||||
}
|
||||
|
||||
static void ticker_op_cb(uint32_t status, void *param)
|
||||
{
|
||||
*((uint32_t volatile *)param) = status;
|
||||
}
|
||||
|
||||
@ -91,8 +91,6 @@ 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 {
|
||||
|
||||
@ -1299,7 +1299,7 @@ void ticker_worker(void *param)
|
||||
struct ticker_expire_info_internal *expire_info;
|
||||
struct ticker_ext_context ext_context;
|
||||
ticker_timeout_func timeout_func;
|
||||
|
||||
|
||||
timeout_func = ticker->ext_data->ext_timeout_func;
|
||||
expire_info = ticker->ext_data->other_expire_info;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user