Bluetooth: controller: Implements ULL Sync ISO ticker

Implements the ull_sync_iso_setup function which starts the
ticker for ISO sync. Furthermore, ll_big_sync_terminate
will not stop the ticker as well.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
Emil Gydesen 2020-11-12 14:49:18 +01:00 committed by Carles Cufí
commit 47aa17bb5c
3 changed files with 121 additions and 13 deletions

View file

@ -79,6 +79,11 @@ enum {
TICKER_ID_SCAN_SYNC_BASE, TICKER_ID_SCAN_SYNC_BASE,
TICKER_ID_SCAN_SYNC_LAST = ((TICKER_ID_SCAN_SYNC_BASE) + TICKER_ID_SCAN_SYNC_LAST = ((TICKER_ID_SCAN_SYNC_BASE) +
(CONFIG_BT_CTLR_SCAN_SYNC_SET) - 1), (CONFIG_BT_CTLR_SCAN_SYNC_SET) - 1),
#if defined(CONFIG_BT_CTLR_SYNC_ISO)
TICKER_ID_SCAN_SYNC_ISO_BASE,
TICKER_ID_SCAN_SYNC_ISO_LAST = ((TICKER_ID_SCAN_SYNC_ISO_BASE) +
(CONFIG_BT_CTLR_SCAN_SYNC_ISO_MAX) - 1),
#endif /* CONFIG_BT_CTLR_SYNC_ISO */
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */ #endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
#endif /* CONFIG_BT_CTLR_ADV_EXT */ #endif /* CONFIG_BT_CTLR_ADV_EXT */
#endif /* CONFIG_BT_OBSERVER */ #endif /* CONFIG_BT_OBSERVER */

View file

@ -11,6 +11,8 @@
#include "common/log.h" #include "common/log.h"
#include "hal/debug.h" #include "hal/debug.h"
#include <sys/byteorder.h>
#include "util/util.h" #include "util/util.h"
#include "util/mem.h" #include "util/mem.h"
#include "util/memq.h" #include "util/memq.h"
@ -45,6 +47,9 @@ static void *sync_iso_free;
static int init_reset(void); static int init_reset(void);
static inline struct ll_sync_iso *sync_iso_acquire(void); static inline struct ll_sync_iso *sync_iso_acquire(void);
static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, void *param);
static void ticker_op_cb(uint32_t status, void *param);
uint8_t ll_big_sync_create(uint8_t big_handle, uint16_t sync_handle, uint8_t ll_big_sync_create(uint8_t big_handle, uint16_t sync_handle,
uint8_t encryption, uint8_t *bcode, uint8_t mse, uint8_t encryption, uint8_t *bcode, uint8_t mse,
@ -97,7 +102,7 @@ uint8_t ll_big_sync_terminate(uint8_t big_handle)
memq_link_t *big_sync_estab; memq_link_t *big_sync_estab;
memq_link_t *big_sync_lost; memq_link_t *big_sync_lost;
struct ll_sync_iso *sync_iso; struct ll_sync_iso *sync_iso;
void *mark; int err;
sync_iso = ull_sync_iso_get(big_handle); sync_iso = ull_sync_iso_get(big_handle);
if (!sync_iso) { if (!sync_iso) {
@ -108,13 +113,14 @@ uint8_t ll_big_sync_terminate(uint8_t big_handle)
return BT_HCI_ERR_CMD_DISALLOWED; return BT_HCI_ERR_CMD_DISALLOWED;
} }
mark = ull_disable_mark(sync_iso);
LL_ASSERT(mark == sync_iso);
/* TODO: Stop ticker */ /* TODO: Stop ticker */
err = ull_ticker_stop_with_mark(
mark = ull_disable_unmark(sync_iso); TICKER_ID_SCAN_SYNC_ISO_BASE + big_handle,
LL_ASSERT(mark == sync_iso); sync_iso, &sync_iso->lll);
LL_ASSERT(err == 0 || err == -EALREADY);
if (err) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
big_sync_lost = sync_iso->node_rx_lost.link; big_sync_lost = sync_iso->node_rx_lost.link;
ll_rx_link_release(big_sync_lost); ll_rx_link_release(big_sync_lost);
@ -181,12 +187,60 @@ void ull_sync_iso_setup(struct ll_sync_iso *sync_iso,
struct node_rx_hdr *node_rx, struct node_rx_hdr *node_rx,
struct pdu_biginfo *biginfo) struct pdu_biginfo *biginfo)
{ {
/* TODO: Implement and start ticker. uint16_t handle;
* Depends on ACAD (biginfo) support struct node_rx_sync_iso *se;
*/ uint16_t interval;
ARG_UNUSED(sync_iso); uint32_t interval_us;
ARG_UNUSED(node_rx); uint32_t ticks_slot_overhead;
ARG_UNUSED(biginfo); uint32_t ticks_slot_offset;
uint32_t ret;
struct node_rx_ftr *ftr;
uint32_t sync_offset_us;
struct node_rx_pdu *rx;
struct lll_sync_iso *lll;
lll = &sync_iso->lll;
handle = ull_sync_iso_handle_get(sync_iso);
interval = sys_le16_to_cpu(biginfo->iso_interval);
interval_us = interval * 1250U;
/* TODO: Populate LLL with information from the BIGINFO */
rx = (void *)sync_iso->node_rx_estab.link;
rx->hdr.type = NODE_RX_TYPE_SYNC_ISO;
rx->hdr.handle = handle;
rx->hdr.rx_ftr.param = sync_iso;
se = (void *)rx->pdu;
se->status = BT_HCI_ERR_SUCCESS;
se->interval = interval;
ll_rx_put(rx->hdr.link, rx);
ll_rx_sched();
ftr = &node_rx->rx_ftr;
/* TODO: Calculate offset */
sync_offset_us = 0;
ticks_slot_offset = 0;
if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) {
ticks_slot_overhead = ticks_slot_offset;
} else {
ticks_slot_overhead = 0U;
}
ret = ticker_start(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH,
(TICKER_ID_SCAN_SYNC_ISO_BASE + handle),
ftr->ticks_anchor - ticks_slot_offset,
HAL_TICKER_US_TO_TICKS(sync_offset_us),
HAL_TICKER_US_TO_TICKS(interval_us),
HAL_TICKER_REMAINDER(interval_us),
TICKER_NULL_LAZY,
ticks_slot_overhead,
ticker_cb, sync_iso, ticker_op_cb, (void *)__LINE__);
LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
(ret == TICKER_STATUS_BUSY));
} }
static int init_reset(void) static int init_reset(void)
@ -203,3 +257,47 @@ static inline struct ll_sync_iso *sync_iso_acquire(void)
{ {
return mem_acquire(&sync_iso_free); return mem_acquire(&sync_iso_free);
} }
static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, void *param)
{
/* TODO: Implement LLL handling */
#if 0
static memq_link_t link;
static struct mayfly mfy = {0, 0, &link, NULL, lll_sync_prepare};
static struct lll_prepare_param p;
struct ll_sync_set *sync = param;
struct lll_sync *lll;
uint32_t ret;
uint8_t ref;
DEBUG_RADIO_PREPARE_O(1);
lll = &sync->lll;
/* Increment prepare reference count */
ref = ull_ref_inc(&sync->ull);
LL_ASSERT(ref);
/* Append timing parameters */
p.ticks_at_expire = ticks_at_expire;
p.remainder = remainder;
p.lazy = lazy;
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);
DEBUG_RADIO_PREPARE_O(1);
#endif
}
static void ticker_op_cb(uint32_t status, void *param)
{
ARG_UNUSED(param);
LL_ASSERT(status == TICKER_STATUS_SUCCESS);
}

View file

@ -17,6 +17,11 @@ struct ll_sync_iso {
struct node_rx_hdr node_rx_lost; struct node_rx_hdr node_rx_lost;
struct node_rx_hdr node_rx_estab; struct node_rx_hdr node_rx_estab;
}; };
struct node_rx_sync_iso {
uint8_t status;
uint16_t interval;
};
#endif /* CONFIG_BT_CTLR_SYNC_ISO */ #endif /* CONFIG_BT_CTLR_SYNC_ISO */
struct ll_sync_set { struct ll_sync_set {