Skip to content
Permalink
Browse files

Bluetooth: controller: split: Port radio event abort

Port the implementation that does radio event abort due to
ISR latencies. The implementation measures if the ISR could
not meet the hard real time deadline and closes the event
early.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
  • Loading branch information...
cvinayak authored and aescolar committed Jun 7, 2019
1 parent 3aa5780 commit a02151ebd42eef7f9088f720e80f37edbaa34690
@@ -17,11 +17,12 @@

#include "util/mem.h"
#include "util/memq.h"

#include "util/mayfly.h"

#include "ticker/ticker.h"

#include "lll.h"
#include "lll_vendor.h"
#include "lll_internal.h"

#define LOG_MODULE_NAME bt_ctlr_llsw_nordic_lll
@@ -358,11 +359,25 @@ u32_t lll_evt_offset_get(struct evt_hdr *evt)
u32_t lll_preempt_calc(struct evt_hdr *evt, u8_t ticker_id,
u32_t ticks_at_event)
{
/* TODO: */
u32_t ticks_now = ticker_ticks_now_get();
u32_t diff;

diff = ticker_ticks_diff_get(ticks_now, ticks_at_event);
diff += HAL_TICKER_CNTR_CMP_OFFSET_MIN;
if (!(diff & BIT(HAL_TICKER_CNTR_MSBIT)) &&
(diff > HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US))) {
/* TODO: for Low Latency Feature with Advanced XTAL feature.
* 1. Release retained HF clock.
* 2. Advance the radio event to accommodate normal prepare
* duration.
* 3. Increase the preempt to start ticks for future events.
*/
return 1;
}

return 0;
}


void lll_chan_set(u32_t chan)
{
switch (chan) {
@@ -119,7 +119,7 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
{
struct lll_adv *lll = prepare_param->param;
u32_t aa = sys_cpu_to_le32(0x8e89bed6);
u32_t ticks_at_event;
u32_t ticks_at_event, ticks_at_start;
struct evt_hdr *evt;
u32_t remainder_us;
u32_t remainder;
@@ -191,10 +191,12 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
ticks_at_event = prepare_param->ticks_at_expire;
evt = HDR_LLL2EVT(lll);
ticks_at_event += lll_evt_offset_get(evt);
ticks_at_event += HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);

ticks_at_start = ticks_at_event;
ticks_at_start += HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);

remainder = prepare_param->remainder;
remainder_us = radio_tmr_start(1, ticks_at_event, remainder);
remainder_us = radio_tmr_start(1, ticks_at_start, remainder);

/* capture end of Tx-ed PDU, used to calculate HCTO. */
radio_tmr_end_capture();
@@ -211,7 +213,9 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
#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_ADV_BASE, ticks_at_event)) {
if (lll_preempt_calc(evt, (TICKER_ID_ADV_BASE +
ull_adv_lll_handle_get(lll)),
ticks_at_event)) {
radio_isr_set(isr_abort, lll);
radio_disable();
} else
@@ -80,8 +80,8 @@ static int init_reset(void)
static int prepare_cb(struct lll_prepare_param *prepare_param)
{
struct lll_conn *lll = prepare_param->param;
u32_t ticks_at_event, ticks_at_start;
struct pdu_data *pdu_data_tx;
u32_t ticks_at_event;
struct evt_hdr *evt;
u16_t event_counter;
u32_t remainder_us;
@@ -162,10 +162,12 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
ticks_at_event = prepare_param->ticks_at_expire;
evt = HDR_LLL2EVT(lll);
ticks_at_event += lll_evt_offset_get(evt);
ticks_at_event += HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);

ticks_at_start = ticks_at_event;
ticks_at_start += HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);

remainder = prepare_param->remainder;
remainder_us = radio_tmr_start(1, ticks_at_event, remainder);
remainder_us = radio_tmr_start(1, ticks_at_start, remainder);

/* capture end of Tx-ed PDU, used to calculate HCTO. */
radio_tmr_end_capture();
@@ -190,7 +192,8 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
#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, ticks_at_event)) {
if (lll_preempt_calc(evt, (TICKER_ID_CONN_BASE + lll->handle),
ticks_at_event)) {
radio_isr_set(lll_conn_isr_abort, lll);
radio_disable();
} else
@@ -116,9 +116,9 @@ static int init_reset(void)
static int prepare_cb(struct lll_prepare_param *prepare_param)
{
struct lll_scan *lll = prepare_param->param;
struct node_rx_pdu *node_rx;
u32_t aa = sys_cpu_to_le32(0x8e89bed6);
u32_t ticks_at_event;
u32_t ticks_at_event, ticks_at_start;
struct node_rx_pdu *node_rx;
struct evt_hdr *evt;
u32_t remainder_us;
u32_t remainder;
@@ -196,10 +196,12 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
ticks_at_event = prepare_param->ticks_at_expire;
evt = HDR_LLL2EVT(lll);
ticks_at_event += lll_evt_offset_get(evt);
ticks_at_event += HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);

ticks_at_start = ticks_at_event;
ticks_at_start += HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);

remainder = prepare_param->remainder;
remainder_us = radio_tmr_start(0, ticks_at_event, remainder);
remainder_us = radio_tmr_start(0, ticks_at_start, remainder);

/* capture end of Rx-ed PDU, for initiator to calculate first
* master event.
@@ -221,7 +223,9 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
#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_SCAN_BASE, ticks_at_event)) {
if (lll_preempt_calc(evt, (TICKER_ID_SCAN_BASE +
ull_scan_lll_handle_get(lll)),
ticks_at_event)) {
radio_isr_set(isr_abort, lll);
radio_disable();
} else
@@ -80,7 +80,7 @@ static int init_reset(void)
static int prepare_cb(struct lll_prepare_param *prepare_param)
{
struct lll_conn *lll = prepare_param->param;
u32_t ticks_at_event;
u32_t ticks_at_event, ticks_at_start;
struct evt_hdr *evt;
u16_t event_counter;
u32_t remainder_us;
@@ -185,10 +185,12 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
ticks_at_event = prepare_param->ticks_at_expire;
evt = HDR_LLL2EVT(lll);
ticks_at_event += lll_evt_offset_get(evt);
ticks_at_event += HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);

ticks_at_start = ticks_at_event;
ticks_at_start += HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);

remainder = prepare_param->remainder;
remainder_us = radio_tmr_start(0, ticks_at_event, remainder);
remainder_us = radio_tmr_start(0, ticks_at_start, remainder);

radio_tmr_aa_capture();
radio_tmr_aa_save(0);
@@ -235,7 +237,8 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
#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, ticks_at_event)) {
if (lll_preempt_calc(evt, (TICKER_ID_CONN_BASE + lll->handle),
ticks_at_event)) {
radio_isr_set(lll_conn_isr_abort, lll);
radio_disable();
} else

0 comments on commit a02151e

Please sign in to comment.
You can’t perform that action at this time.