Bluetooth: controller: split: Add periodic adv ULL implementation

Add ULL implementation to perform periodic advertising.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2020-03-13 16:24:01 +05:30 committed by Carles Cufí
commit 3eac6c3a52
15 changed files with 431 additions and 34 deletions

View file

@ -31,6 +31,10 @@ if(CONFIG_BT_LL_SW_SPLIT)
CONFIG_BT_CTLR_ADV_EXT
ll_sw/ull_adv_aux.c
)
zephyr_library_sources_ifdef(
CONFIG_BT_CTLR_ADV_PERIODIC
ll_sw/ull_adv_sync.c
)
endif()
if(CONFIG_BT_OBSERVER)
zephyr_library_sources(

View file

@ -35,6 +35,10 @@ config BT_CTLR_PHY_UPDATE_SUPPORT
config BT_CTLR_ADV_EXT_SUPPORT
bool
config BT_CTLR_ADV_PERIODIC_SUPPORT
depends on BT_CTLR_ADV_EXT_SUPPORT
bool
config BT_CTLR_CHAN_SEL_2_SUPPORT
bool
@ -95,6 +99,7 @@ config BT_LLL_VENDOR_NORDIC
select BT_CTLR_PHY_UPDATE_SUPPORT if !SOC_SERIES_NRF51X || \
BT_CTLR_PHY_2M_NRF
select BT_CTLR_ADV_EXT_SUPPORT
select BT_CTLR_ADV_PERIODIC_SUPPORT
select BT_CTLR_CHAN_SEL_2_SUPPORT
select BT_CTLR_MIN_USED_CHAN_SUPPORT
select BT_CTLR_DTM_HCI_SUPPORT
@ -448,13 +453,27 @@ config BT_CTLR_ADV_EXT
Enable support for Bluetooth 5.0 LE Advertising Extensions in the
Controller.
config BT_ADV_SET
config BT_CTLR_ADV_SET
int "LE Advertising Extensions Sets"
depends on BT_CTLR_ADV_EXT
default 1
help
Maximum supported advertising sets.
config BT_CTLR_ADV_PERIODIC
bool "LE Periodic Advertising"
depends on BT_CTLR_ADV_EXT
help
Enable support for Bluetooth 5.0 LE Periodic Advertising in the
Controller.
config BT_CTLR_ADV_SYNC_SET
int "LE Periodic Advertising Sets"
depends on BT_CTLR_ADV_PERIODIC
default 1
help
Maximum supported periodic advertising sets.
config BT_CTLR_DTM
bool
help

View file

@ -19,8 +19,10 @@ uint8_t ll_adv_params_set(uint8_t handle, uint16_t evt_prop, uint32_t interval,
uint8_t direct_addr_type, uint8_t const *const direct_addr,
uint8_t chan_map, uint8_t filter_policy, uint8_t *tx_pwr,
uint8_t phy_p, uint8_t skip, uint8_t phy_s, uint8_t sid, uint8_t sreq);
uint8_t ll_adv_data_set(uint16_t handle, uint8_t len, uint8_t const *const p_data);
uint8_t ll_adv_scan_rsp_set(uint16_t handle, uint8_t len, uint8_t const *const p_data);
uint8_t ll_adv_data_set(uint8_t handle, uint8_t len,
uint8_t const *const p_data);
uint8_t ll_adv_scan_rsp_set(uint8_t handle, uint8_t len,
uint8_t const *const p_data);
uint8_t ll_adv_aux_random_addr_set(uint8_t handle, uint8_t *addr);
uint8_t *ll_adv_aux_random_addr_get(uint8_t handle, uint8_t *addr);
uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref,
@ -31,6 +33,11 @@ uint16_t ll_adv_aux_max_data_length_get(void);
uint8_t ll_adv_aux_set_count_get(void);
uint8_t ll_adv_aux_set_remove(uint8_t handle);
uint8_t ll_adv_aux_set_clear(void);
uint8_t ll_adv_sync_param_set(uint8_t handle, uint16_t interval,
uint16_t flags);
uint8_t ll_adv_sync_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref,
uint8_t len, uint8_t *data);
uint8_t ll_adv_sync_enable(uint8_t handle, uint8_t enable);
#else /* !CONFIG_BT_CTLR_ADV_EXT */
uint8_t ll_adv_params_set(uint16_t interval, uint8_t adv_type,
uint8_t own_addr_type, uint8_t direct_addr_type,
@ -42,11 +49,11 @@ uint8_t ll_adv_scan_rsp_set(uint8_t len, uint8_t const *const p_data);
#if defined(CONFIG_BT_CTLR_ADV_EXT) || defined(CONFIG_BT_HCI_MESH_EXT)
#if defined(CONFIG_BT_HCI_MESH_EXT)
uint8_t ll_adv_enable(uint16_t handle, uint8_t enable,
uint8_t ll_adv_enable(uint8_t handle, uint8_t enable,
uint8_t at_anchor, uint32_t ticks_anchor, uint8_t retry,
uint8_t scan_window, uint8_t scan_delay);
#else /* !CONFIG_BT_HCI_MESH_EXT */
uint8_t ll_adv_enable(uint16_t handle, uint8_t enable);
uint8_t ll_adv_enable(uint8_t handle, uint8_t enable);
#endif /* !CONFIG_BT_HCI_MESH_EXT */
#else /* !CONFIG_BT_CTLR_ADV_EXT || !CONFIG_BT_HCI_MESH_EXT */
uint8_t ll_adv_enable(uint8_t enable);

View file

@ -17,7 +17,10 @@
#include "pdu.h"
#include "lll.h"
#include "lll_adv.h"
#include "lll_scan.h"
#include "ull_adv_types.h"
#include "ull_scan_types.h"
#include "ull_adv_internal.h"
#include "ull_scan_internal.h"

View file

@ -25,8 +25,8 @@
#define XON_BITMASK BIT(31) /* XTAL has been retained from previous prepare */
#endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */
#if defined(CONFIG_BT_BROADCASTER) && defined(CONFIG_BT_ADV_SET)
#define BT_CTLR_ADV_MAX (CONFIG_BT_ADV_SET + 1)
#if defined(CONFIG_BT_BROADCASTER) && defined(CONFIG_BT_CTLR_ADV_SET)
#define BT_CTLR_ADV_MAX (CONFIG_BT_CTLR_ADV_SET + 1)
#else
#define BT_CTLR_ADV_MAX 1
#endif
@ -39,9 +39,20 @@ enum {
TICKER_ID_ADV_BASE,
#if defined(CONFIG_BT_CTLR_ADV_EXT) || defined(CONFIG_BT_HCI_MESH_EXT)
TICKER_ID_ADV_LAST = ((TICKER_ID_ADV_BASE) + (BT_CTLR_ADV_MAX) - 1),
#if defined(CONFIG_BT_CTLR_ADV_EXT)
TICKER_ID_ADV_AUX_BASE,
TICKER_ID_ADV_AUX_LAST = ((TICKER_ID_ADV_AUX_BASE) +
(CONFIG_BT_CTLR_ADV_SET) - 1),
#endif /* CONFIG_BT_CTLR_ADV_EXT */
#endif /* !CONFIG_BT_CTLR_ADV_EXT || !CONFIG_BT_HCI_MESH_EXT */
#endif /* CONFIG_BT_BROADCASTER */
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
TICKER_ID_ADV_SYNC_BASE,
TICKER_ID_ADV_SYNC_LAST = ((TICKER_ID_ADV_SYNC_BASE) +
(CONFIG_BT_CTLR_ADV_SYNC_SET) - 1),
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
#if defined(CONFIG_BT_OBSERVER)
TICKER_ID_SCAN_STOP,
TICKER_ID_SCAN_BASE,

View file

@ -13,6 +13,15 @@ struct lll_adv_pdu {
uint8_t pdu[DOUBLE_BUFFER_SIZE][PDU_AC_SIZE_MAX];
};
struct lll_adv_sync {
struct lll_hdr hdr;
uint8_t access_addr[4];
uint8_t crc_init[3];
struct lll_adv_pdu data;
};
struct lll_adv {
struct lll_hdr hdr;
@ -43,6 +52,10 @@ struct lll_adv {
#if defined(CONFIG_BT_CTLR_ADV_EXT)
struct lll_adv_pdu aux_data;
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
struct lll_adv_sync *sync;
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
#endif /* CONFIG_BT_CTLR_ADV_EXT */
#if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL)
@ -126,6 +139,25 @@ static inline struct pdu_adv *lll_adv_aux_data_peek(struct lll_adv *lll)
{
return (void *)lll->aux_data.pdu[lll->aux_data.last];
}
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
static inline struct pdu_adv *lll_adv_sync_data_alloc(struct lll_adv_sync *lll,
uint8_t *idx)
{
return lll_adv_pdu_alloc(&lll->data, idx);
}
static inline void lll_adv_sync_data_enqueue(struct lll_adv_sync *lll,
uint8_t idx)
{
lll_adv_pdu_enqueue(&lll->data, idx);
}
static inline struct pdu_adv *lll_adv_sync_data_peek(struct lll_adv_sync *lll)
{
return (void *)lll->data.pdu[lll->data.last];
}
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
#endif /* CONFIG_BT_CTLR_ADV_EXT */
extern uint16_t ull_adv_lll_handle_get(struct lll_adv *lll);

View file

@ -55,4 +55,18 @@ static inline struct pdu_adv *lll_adv_aux_data_curr_get(struct lll_adv *lll)
{
return (void *)lll->aux_data.pdu[lll->aux_data.first];
}
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
static inline struct pdu_adv *
lll_adv_sync_data_latest_get(struct lll_adv_sync *lll, uint8_t *is_modified)
{
return lll_adv_pdu_latest_get(&lll->data, is_modified);
}
static inline struct pdu_adv *
lll_adv_sync_data_curr_get(struct lll_adv_sync *lll)
{
return (void *)lll->data.pdu[lll->data.first];
}
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
#endif /* CONFIG_BT_CTLR_ADV_EXT */

View file

@ -52,11 +52,11 @@
#define ULL_ADV_RANDOM_DELAY HAL_TICKER_US_TO_TICKS(10000)
inline struct ll_adv_set *ull_adv_set_get(uint16_t handle);
inline struct ll_adv_set *ull_adv_set_get(uint8_t handle);
inline uint16_t ull_adv_handle_get(struct ll_adv_set *adv);
static int init_reset(void);
static inline struct ll_adv_set *is_disabled_get(uint16_t handle);
static inline struct ll_adv_set *is_disabled_get(uint8_t handle);
static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder, uint16_t lazy,
void *param);
static void ticker_op_update_cb(uint32_t status, void *params);
@ -69,7 +69,7 @@ static void disabled_cb(void *param);
static void conn_release(struct ll_adv_set *adv);
#endif /* CONFIG_BT_PERIPHERAL */
static inline uint8_t disable(uint16_t handle);
static inline uint8_t disable(uint8_t handle);
static struct ll_adv_set ll_adv[BT_CTLR_ADV_MAX];
@ -102,7 +102,7 @@ uint8_t ll_adv_params_set(uint16_t interval, uint8_t adv_type,
PDU_ADV_TYPE_SCAN_IND,
PDU_ADV_TYPE_NONCONN_IND,
PDU_ADV_TYPE_DIRECT_IND};
uint16_t const handle = 0;
uint8_t const handle = 0;
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
struct ll_adv_set *adv;
@ -367,12 +367,12 @@ uint8_t ll_adv_params_set(uint16_t interval, uint8_t adv_type,
}
#if defined(CONFIG_BT_CTLR_ADV_EXT)
uint8_t ll_adv_data_set(uint16_t handle, uint8_t len, uint8_t const *const data)
uint8_t ll_adv_data_set(uint8_t handle, uint8_t len, uint8_t const *const data)
{
#else /* !CONFIG_BT_CTLR_ADV_EXT */
uint8_t ll_adv_data_set(uint8_t len, uint8_t const *const data)
{
const uint16_t handle = 0;
const uint8_t handle = 0;
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
struct ll_adv_set *adv;
struct pdu_adv *prev;
@ -418,12 +418,13 @@ uint8_t ll_adv_data_set(uint8_t len, uint8_t const *const data)
}
#if defined(CONFIG_BT_CTLR_ADV_EXT)
uint8_t ll_adv_scan_rsp_set(uint16_t handle, uint8_t len, uint8_t const *const data)
uint8_t ll_adv_scan_rsp_set(uint8_t handle, uint8_t len,
uint8_t const *const data)
{
#else /* !CONFIG_BT_CTLR_ADV_EXT */
uint8_t ll_adv_scan_rsp_set(uint8_t len, uint8_t const *const data)
{
const uint16_t handle = 0;
const uint8_t handle = 0;
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
struct ll_adv_set *adv;
struct pdu_adv *prev;
@ -454,19 +455,23 @@ uint8_t ll_adv_scan_rsp_set(uint8_t len, uint8_t const *const data)
#if defined(CONFIG_BT_CTLR_ADV_EXT) || defined(CONFIG_BT_HCI_MESH_EXT)
#if defined(CONFIG_BT_HCI_MESH_EXT)
uint8_t ll_adv_enable(uint16_t handle, uint8_t enable,
uint8_t ll_adv_enable(uint8_t handle, uint8_t enable,
uint8_t at_anchor, uint32_t ticks_anchor, uint8_t retry,
uint8_t scan_window, uint8_t scan_delay)
{
#else /* !CONFIG_BT_HCI_MESH_EXT */
uint8_t ll_adv_enable(uint16_t handle, uint8_t enable)
uint8_t ll_adv_enable(uint8_t handle, uint8_t enable)
{
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
struct ll_adv_sync_set *sync;
uint8_t sync_is_started = 0U;
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
uint32_t ticks_anchor;
#endif /* !CONFIG_BT_HCI_MESH_EXT */
#else /* !CONFIG_BT_CTLR_ADV_EXT || !CONFIG_BT_HCI_MESH_EXT */
uint8_t ll_adv_enable(uint8_t enable)
{
uint16_t const handle = 0;
uint8_t const handle = 0;
uint32_t ticks_anchor;
#endif /* !CONFIG_BT_CTLR_ADV_EXT || !CONFIG_BT_HCI_MESH_EXT */
volatile uint32_t ret_cb = TICKER_STATUS_BUSY;
@ -976,6 +981,25 @@ uint8_t ll_adv_enable(uint8_t enable)
&ll_adv_ticker_ext[handle]
#endif /* CONFIG_BT_TICKER_EXT */
);
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
if (lll->sync) {
struct lll_adv_sync *lll_sync = lll->sync;
sync = (void *)HDR_LLL2EVT(lll_sync);
if (sync->is_enabled && !sync->is_started) {
ret = ull_ticker_status_take(ret, &ret_cb);
if (ret != TICKER_STATUS_SUCCESS) {
goto failure_cleanup;
}
ret = ull_adv_sync_start(sync, ticks_anchor,
&ret_cb);
sync_is_started = 1U;
}
}
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
}
ret = ull_ticker_status_take(ret, &ret_cb);
@ -983,6 +1007,12 @@ uint8_t ll_adv_enable(uint8_t enable)
goto failure_cleanup;
}
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
if (sync_is_started) {
sync->is_started = sync_is_started;
}
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
adv->is_enabled = 1;
#if defined(CONFIG_BT_CTLR_PRIVACY)
@ -1026,7 +1056,7 @@ int ull_adv_init(void)
int ull_adv_reset(void)
{
uint16_t handle;
uint8_t handle;
int err;
for (handle = 0U; handle < BT_CTLR_ADV_MAX; handle++) {
@ -1041,7 +1071,7 @@ int ull_adv_reset(void)
return 0;
}
inline struct ll_adv_set *ull_adv_set_get(uint16_t handle)
inline struct ll_adv_set *ull_adv_set_get(uint8_t handle)
{
if (handle >= BT_CTLR_ADV_MAX) {
return NULL;
@ -1060,7 +1090,7 @@ uint16_t ull_adv_lll_handle_get(struct lll_adv *lll)
return ull_adv_handle_get((void *)lll->hdr.parent);
}
inline struct ll_adv_set *ull_adv_is_enabled_get(uint16_t handle)
inline struct ll_adv_set *ull_adv_is_enabled_get(uint8_t handle)
{
struct ll_adv_set *adv;
@ -1072,7 +1102,7 @@ inline struct ll_adv_set *ull_adv_is_enabled_get(uint16_t handle)
return adv;
}
uint32_t ull_adv_is_enabled(uint16_t handle)
uint32_t ull_adv_is_enabled(uint8_t handle)
{
struct ll_adv_set *adv;
@ -1084,7 +1114,7 @@ uint32_t ull_adv_is_enabled(uint16_t handle)
return BIT(0);
}
uint32_t ull_adv_filter_pol_get(uint16_t handle)
uint32_t ull_adv_filter_pol_get(uint8_t handle)
{
struct ll_adv_set *adv;
@ -1101,7 +1131,7 @@ static int init_reset(void)
return 0;
}
static inline struct ll_adv_set *is_disabled_get(uint16_t handle)
static inline struct ll_adv_set *is_disabled_get(uint8_t handle)
{
struct ll_adv_set *adv;
@ -1184,7 +1214,7 @@ static void ticker_stop_cb(uint32_t ticks_at_expire, uint32_t remainder, uint16_
void *param)
{
struct ll_adv_set *adv = param;
uint16_t handle;
uint8_t handle;
uint32_t ret;
#if 0
@ -1306,7 +1336,7 @@ static void conn_release(struct ll_adv_set *adv)
}
#endif /* CONFIG_BT_PERIPHERAL */
static inline uint8_t disable(uint16_t handle)
static inline uint8_t disable(uint8_t handle)
{
volatile uint32_t ret_cb = TICKER_STATUS_BUSY;
struct ll_adv_set *adv;

View file

@ -1,12 +1,12 @@
/*
* Copyright (c) 2017-2019 Nordic Semiconductor ASA
* Copyright (c) 2017-2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <zephyr.h>
#include <zephyr/types.h>
#include <bluetooth/hci.h>
#include "hal/ccm.h"

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2019 Nordic Semiconductor ASA
* Copyright (c) 2017-2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -8,16 +8,20 @@ int ull_adv_init(void);
int ull_adv_reset(void);
/* Return ll_adv_set context (unconditional) */
struct ll_adv_set *ull_adv_set_get(uint16_t handle);
struct ll_adv_set *ull_adv_set_get(uint8_t handle);
/* Return the adv set handle given the adv set instance */
uint16_t ull_adv_handle_get(struct ll_adv_set *adv);
/* Return ll_adv_set context if enabled */
struct ll_adv_set *ull_adv_is_enabled_get(uint16_t handle);
struct ll_adv_set *ull_adv_is_enabled_get(uint8_t handle);
/* Return flags, for now just: enabled */
uint32_t ull_adv_is_enabled(uint16_t handle);
uint32_t ull_adv_is_enabled(uint8_t handle);
/* Return filter policy used */
uint32_t ull_adv_filter_pol_get(uint16_t handle);
uint32_t ull_adv_filter_pol_get(uint8_t handle);
/* helper function to start periodic advertising */
uint32_t ull_adv_sync_start(struct ll_adv_sync_set *sync, uint32_t ticks_anchor,
uint32_t volatile *ret_cb);

View file

@ -0,0 +1,260 @@
/*
* Copyright (c) 2017-2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/types.h>
#include <bluetooth/hci.h>
#include "hal/ticker.h"
#include "util/util.h"
#include "util/mem.h"
#include "util/memq.h"
#include "util/mayfly.h"
#include "ticker/ticker.h"
#include "pdu.h"
#include "ll.h"
#include "lll.h"
#include "lll_vendor.h"
#include "lll_adv.h"
#include "ull_adv_types.h"
#include "ull_internal.h"
#include "ull_adv_internal.h"
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
#define LOG_MODULE_NAME bt_ctlr_ull_adv_sync
#include "common/log.h"
#include <soc.h>
#include "hal/debug.h"
static int init_reset(void);
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 void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, void *param);
static struct ll_adv_sync_set ll_adv_sync_pool[CONFIG_BT_CTLR_ADV_SYNC_SET];
static void *adv_sync_free;
uint8_t ll_adv_sync_param_set(uint8_t handle, uint16_t interval, uint16_t flags)
{
struct lll_adv_sync *lll;
struct ll_adv_sync_set *sync;
struct ll_adv_set *adv;
struct pdu_adv *pdu;
adv = ull_adv_is_enabled_get(handle);
if (!adv) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
lll = adv->lll.sync;
if (!lll) {
sync = sync_acquire();
if (!sync) {
return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
}
lll = &sync->lll;
adv->lll.sync = lll;
} else {
sync = (void *)HDR_LLL2EVT(lll);
}
sync->interval = interval;
pdu = lll_adv_sync_data_peek(lll);
pdu->type = PDU_ADV_TYPE_AUX_SYNC_IND;
pdu->rfu = 0U;
pdu->chan_sel = 0U;
pdu->tx_addr = 0U;
pdu->rx_addr = 0U;
if (flags & BIT(6)) {
/* TODO: add/remove Tx Power in AUX_SYNC_IND PDU */
return BT_HCI_ERR_CMD_DISALLOWED;
}
return 0;
}
uint8_t ll_adv_sync_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref,
uint8_t len, uint8_t *data)
{
/* TODO */
return BT_HCI_ERR_CMD_DISALLOWED;
}
uint8_t ll_adv_sync_enable(uint8_t handle, uint8_t enable)
{
struct lll_adv_sync *lll_sync;
struct ll_adv_sync_set *sync;
struct ll_adv_set *adv;
adv = ull_adv_is_enabled_get(handle);
if (!adv) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
lll_sync = adv->lll.sync;
if (!lll_sync) {
return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
}
sync = (void *)HDR_LLL2EVT(lll_sync);
if (!enable) {
/* TODO */
return BT_HCI_ERR_CMD_DISALLOWED;
}
/* TODO: Check for periodic data being complete */
/* TODO: Check packet too long */
if (sync->is_enabled) {
/* TODO: Enabling an already enabled advertising changes its
* random address.
*/
} else {
sync->is_enabled = 1U;
}
if (!sync->is_started) {
}
return 0;
}
int ull_adv_sync_init(void)
{
int err;
err = init_reset();
if (err) {
return err;
}
return 0;
}
int ull_adv_sync_reset(void)
{
int err;
err = init_reset();
if (err) {
return err;
}
return 0;
}
uint32_t ull_adv_sync_start(struct ll_adv_sync_set *sync, uint32_t ticks_anchor,
uint32_t volatile *ret_cb)
{
uint32_t slot_us, ticks_slot_offset, ticks_slot_overhead;
uint8_t sync_handle;
uint32_t ret;
/* TODO: Calc AUX_SYNC_IND slot_us */
slot_us = 0;
/* TODO: active_to_start feature port */
sync->evt.ticks_active_to_start = 0;
sync->evt.ticks_xtal_to_start =
HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US);
sync->evt.ticks_preempt_to_start =
HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US);
sync->evt.ticks_slot = HAL_TICKER_US_TO_TICKS(slot_us);
ticks_slot_offset = MAX(sync->evt.ticks_active_to_start,
sync->evt.ticks_xtal_to_start);
if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) {
ticks_slot_overhead = ticks_slot_offset;
} else {
ticks_slot_overhead = 0;
}
sync_handle = sync_handle_get(sync);
*ret_cb = TICKER_STATUS_BUSY;
ret = ticker_start(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD,
(TICKER_ID_ADV_SYNC_BASE + sync_handle),
ticks_anchor, 0,
(sync->evt.ticks_slot + ticks_slot_overhead),
TICKER_NULL_REMAINDER, TICKER_NULL_LAZY,
(sync->evt.ticks_slot + ticks_slot_overhead),
ticker_cb, sync,
ull_ticker_status_give, (void *)ret_cb);
return ret;
}
static int init_reset(void)
{
/* Initialize adv sync pool. */
mem_init(ll_adv_sync_pool, sizeof(struct ll_adv_sync_set),
sizeof(ll_adv_sync_pool) / sizeof(struct ll_adv_sync_set),
&adv_sync_free);
return 0;
}
static inline struct ll_adv_sync_set *sync_acquire(void)
{
return mem_acquire(&adv_sync_free);
}
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 void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, void *param)
{
static memq_link_t link;
static struct mayfly mfy = {0, 0, &link, NULL, lll_adv_prepare};
static struct lll_prepare_param p;
struct ll_adv_sync_set *sync = param;
struct lll_adv_sync *lll;
uint32_t ret;
uint8_t ref;
DEBUG_RADIO_PREPARE_A(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_A(1);
}

View file

@ -30,3 +30,14 @@ struct ll_adv_set {
uint8_t id_addr[BDADDR_SIZE];
#endif /* CONFIG_BT_CTLR_PRIVACY */
};
struct ll_adv_sync_set {
struct evt_hdr evt;
struct ull_hdr ull;
struct lll_adv_sync lll;
uint16_t interval;
uint8_t is_enabled:1;
uint8_t is_started:1;
};

View file

@ -60,6 +60,7 @@ void ll_conn_release(struct ll_conn *conn);
uint16_t ll_conn_handle_get(struct ll_conn *conn);
struct ll_conn *ll_conn_get(uint16_t handle);
struct ll_conn *ll_connected_get(uint16_t handle);
void ll_tx_ack_put(uint16_t handle, struct node_tx *node_tx);
int ull_conn_init(void);
int ull_conn_reset(void);
uint8_t ull_conn_chan_map_cpy(uint8_t *chan_map);

View file

@ -27,7 +27,6 @@ void *ll_pdu_rx_alloc_peek(uint8_t count);
void *ll_pdu_rx_alloc(void);
void ll_rx_put(memq_link_t *link, void *rx);
void ll_rx_sched(void);
void ll_tx_ack_put(uint16_t handle, struct node_tx *node_tx);
void ull_ticker_status_give(uint32_t status, void *param);
uint32_t ull_ticker_status_take(uint32_t ret, uint32_t volatile *ret_cb);
void *ull_disable_mark(void *param);

View file

@ -136,9 +136,11 @@ int cmd_test_end(const struct shell *shell, size_t argc, char *argv[])
#define AD_OP 0x03
#define AD_FRAG_PREF 0x00
#if defined(CONFIG_BT_LL_SW_SPLIT)
static const struct bt_data adv_data[] = {
BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_NO_BREDR),
};
#endif
int cmd_advx(const struct shell *shell, size_t argc, char *argv[])
{