Skip to content

Commit

Permalink
Bluetooth: controller: Initial implementation of Periodic Sync setup
Browse files Browse the repository at this point in the history
Added initial implementation of setting up of Periodic Sync
and scheduling the Radio Events.

Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
  • Loading branch information
cvinayak authored and carlescufi committed Oct 7, 2020
1 parent ff4546d commit 057653c
Show file tree
Hide file tree
Showing 9 changed files with 269 additions and 67 deletions.
5 changes: 5 additions & 0 deletions subsys/bluetooth/controller/ll_sw/lll.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ enum {
TICKER_ID_SCAN_AUX_BASE,
TICKER_ID_SCAN_AUX_LAST = ((TICKER_ID_SCAN_AUX_BASE) +
(CONFIG_BT_CTLR_SCAN_AUX_SET) - 1),
#if defined(CONFIG_BT_CTLR_SCAN_PERIODIC)
TICKER_ID_SCAN_SYNC_BASE,
TICKER_ID_SCAN_SYNC_LAST = ((TICKER_ID_SCAN_SYNC_BASE) +
(CONFIG_BT_CTLR_SCAN_SYNC_SET) - 1),
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
#endif /* CONFIG_BT_CTLR_ADV_EXT */
#endif /* CONFIG_BT_OBSERVER */

Expand Down
9 changes: 9 additions & 0 deletions subsys/bluetooth/controller/ll_sw/lll_sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,19 @@ struct lll_sync {
uint8_t data_chan_count:6;
uint16_t data_chan_id;

uint32_t window_widening_periodic_us;
uint32_t window_widening_max_us;
uint32_t window_widening_prepare_us;
uint32_t window_widening_event_us;
uint32_t window_size_prepare_us;
uint32_t window_size_event_us;

uint8_t phy:3;
uint8_t is_enabled:1;
};

int lll_sync_init(void);
int lll_sync_reset(void);
void lll_sync_prepare(void *param);

extern uint16_t ull_sync_lll_handle_get(struct lll_sync *lll);
6 changes: 3 additions & 3 deletions subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,9 @@ void lll_conn_isr_rx(void *param)
uint8_t trx_done;
uint8_t crc_ok;

#if defined(CONFIG_BT_CTLR_PROFILE_ISR)
lll_prof_latency_capture();
#endif /* CONFIG_BT_CTLR_PROFILE_ISR */
if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
lll_prof_latency_capture();
}

/* Read radio status and events */
trx_done = radio_is_done();
Expand Down
83 changes: 67 additions & 16 deletions subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
#include <stdint.h>

#include <toolchain.h>
#include <sys/util.h>

#include "hal/ccm.h"
#include "hal/radio.h"
#include "hal/ticker.h"

#include "util/util.h"
#include "util/memq.h"
Expand All @@ -22,6 +24,8 @@
#include "lll_sync.h"

#include "lll_internal.h"
#include "lll_tim_internal.h"
#include "lll_prof_internal.h"

#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
#define LOG_MODULE_NAME bt_ctlr_lll_sync
Expand All @@ -30,6 +34,8 @@
#include "hal/debug.h"

static int init_reset(void);
static int prepare_cb(struct lll_prepare_param *p);
static void isr_rx(void *param);

int lll_sync_init(void)
{
Expand All @@ -55,7 +61,6 @@ int lll_sync_reset(void)
return 0;
}

#if WIP
void lll_sync_prepare(void *param)
{
struct lll_prepare_param *p;
Expand Down Expand Up @@ -84,19 +89,18 @@ void lll_sync_prepare(void *param)
}

/* Invoke common pipeline handling of prepare */
err = lll_prepare(is_abort_cb, abort_cb, prepare_cb, 0, p);
err = lll_prepare(lll_is_abort_cb, lll_abort_cb, prepare_cb, 0, p);
LL_ASSERT(!err || err == -EINPROGRESS);
}
#endif

static int init_reset(void)
{
return 0;
}

#if WIP
static int prepare_cb(struct lll_prepare_param *p)
{
struct node_rx_pdu *node_rx;
uint32_t ticks_at_event;
uint32_t ticks_at_start;
uint16_t event_counter;
Expand All @@ -107,7 +111,7 @@ static int prepare_cb(struct lll_prepare_param *p)
uint32_t remainder;
uint32_t hcto;

DEBUG_RADIO_START_S(1);
DEBUG_RADIO_START_O(1);

lll = p->param;

Expand Down Expand Up @@ -168,15 +172,9 @@ static int prepare_cb(struct lll_prepare_param *p)

radio_tmr_tifs_set(EVENT_IFS_US);

#if defined(CONFIG_BT_CTLR_PHY)
radio_switch_complete_and_disable();
radio_switch_complete_and_tx(lll->phy_rx, 0, lll->phy_tx,
lll->phy_flags);
#else /* !CONFIG_BT_CTLR_PHY */
radio_switch_complete_and_tx(0, 0, 0, 0);
#endif /* !CONFIG_BT_CTLR_PHY */

ticks_at_event = prepare_param->ticks_at_expire;
ticks_at_event = p->ticks_at_expire;
evt = HDR_LLL2EVT(lll);
ticks_at_event += lll_evt_offset_get(evt);

Expand All @@ -196,7 +194,7 @@ static int prepare_cb(struct lll_prepare_param *p)

#if defined(CONFIG_BT_CTLR_PHY)
hcto += radio_rx_ready_delay_get(lll->phy, 1);
hcto += addr_us_get(lll->phy_rx);
hcto += addr_us_get(lll->phy);
hcto += radio_rx_chain_delay_get(lll->phy, 1);
#else /* !CONFIG_BT_CTLR_PHY */
hcto += radio_rx_ready_delay_get(0, 0);
Expand Down Expand Up @@ -232,7 +230,8 @@ static int prepare_cb(struct lll_prepare_param *p)
#if defined(CONFIG_BT_CTLR_XTAL_ADVANCED) && \
(EVENT_OVERHEAD_PREEMPT_US <= EVENT_OVERHEAD_PREEMPT_MIN_US)
/* check if preempt to start has changed */
if (lll_preempt_calc(evt, (TICKER_ID_CONN_BASE + lll->handle),
if (lll_preempt_calc(evt, (TICKER_ID_SCAN_SYNC_BASE +
ull_sync_lll_handle_get(lll)),
ticks_at_event)) {
radio_isr_set(lll_isr_abort, lll);
radio_disable();
Expand All @@ -245,8 +244,60 @@ static int prepare_cb(struct lll_prepare_param *p)
LL_ASSERT(!ret);
}

DEBUG_RADIO_START_S(1);
DEBUG_RADIO_START_O(1);

printk("SYNC PREPARE\n");
return 0;
}
#endif

static void isr_rx(void *param)
{
uint8_t rssi_ready;
uint8_t trx_done;
uint8_t crc_ok;

/* TODO: may be we dont need to profile, as there is no use of tIFS */
if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
lll_prof_latency_capture();
}

/* Read radio status and events */
trx_done = radio_is_done();
if (trx_done) {
crc_ok = radio_crc_is_valid();
rssi_ready = radio_rssi_is_ready();
} else {
crc_ok = rssi_ready = 0U;
}

/* Clear radio rx status and events */
lll_isr_rx_status_reset();

/* No Rx */
if (!trx_done) {
/* TODO: Combine the early exit with above if-then-else block
*/
printk("RX FAILED\n");

return;
}

if (crc_ok) {
/* TODO: */
printk("CRC OK\n");
} else {
printk("CRC BAD\n");
}

if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
lll_prof_cputime_capture();
}

/* TODO: drift compensation */

lll_isr_cleanup(param);

if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
lll_prof_send();
}
}
2 changes: 1 addition & 1 deletion subsys/bluetooth/controller/ll_sw/ull_adv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1356,7 +1356,7 @@ inline uint16_t ull_adv_handle_get(struct ll_adv_set *adv)

uint16_t ull_adv_lll_handle_get(struct lll_adv *lll)
{
return ull_adv_handle_get((void *)lll->hdr.parent);
return ull_adv_handle_get((void *)HDR_LLL2EVT(lll));
}

inline struct ll_adv_set *ull_adv_is_enabled_get(uint8_t handle)
Expand Down
2 changes: 1 addition & 1 deletion subsys/bluetooth/controller/ll_sw/ull_adv_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ uint32_t ull_adv_sync_start(struct ll_adv_sync_set *sync, uint32_t ticks_anchor,
ticks_slot_overhead = 0;
}

interval_us = (uint64_t)sync->interval * 1250U;
interval_us = (uint32_t)sync->interval * 1250U;

sync_handle = sync_handle_get(sync);

Expand Down
41 changes: 1 addition & 40 deletions subsys/bluetooth/controller/ll_sw/ull_scan_aux.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
static void ticker_op_cb(uint32_t status, void *param);
static void ticker_op_aux_failure(void *param);

static void sync_setup(struct ll_scan_set *scan, uint8_t phy,
struct pdu_adv_sync_info *si);

static struct ll_scan_aux_set ll_scan_aux_pool[CONFIG_BT_CTLR_SCAN_AUX_SET];
static void *scan_aux_free;

Expand Down Expand Up @@ -174,7 +171,7 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx, uint8_t phy)
if (IS_ENABLED(CONFIG_BT_CTLR_SCAN_PERIODIC) && sync &&
adi && (adi->sid == scan->per_scan.sid) &&
(scan->per_scan.state == LL_SYNC_STATE_ADDR_MATCH)) {
sync_setup(scan, aux->lll.phy, si);
ull_sync_setup(scan, aux, rx, si);
}
}

Expand Down Expand Up @@ -401,39 +398,3 @@ static void ticker_op_aux_failure(void *param)
{
flush(param, NULL);
}

static void sync_setup(struct ll_scan_set *scan, uint8_t phy,
struct pdu_adv_sync_info *si)
{
struct ll_sync_set *sync;
struct node_rx_sync *se;
struct node_rx_pdu *rx;
uint16_t interval;
uint16_t handle;
uint8_t sca;

sync = scan->per_scan.sync;
scan->per_scan.sync = NULL;

sync->lll.phy = phy;

handle = ull_sync_handle_get(sync);
interval = sys_le16_to_cpu(si->interval);
sca = (si->sca_chm[4] & 0xC0) >> 5;

rx = (void *)scan->per_scan.node_rx_estab;
rx->hdr.type = NODE_RX_TYPE_SYNC;
rx->hdr.handle = handle;
se = (void *)rx->pdu;
se->status = BT_HCI_ERR_SUCCESS;
se->interval = interval;
se->phy = phy; /* TODO: first set bit? */
se->sca = sca;

rx->hdr.rx_ftr.param = scan;

ll_rx_put(rx->hdr.link, rx);
ll_rx_sched();

/* TODO: start ticker and hence the periodic sync events */
}
Loading

0 comments on commit 057653c

Please sign in to comment.