From a02151ebd42eef7f9088f720e80f37edbaa34690 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 7 Jun 2019 16:50:11 +0200 Subject: [PATCH] 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 --- .../controller/ll_sw/nordic/lll/lll.c | 21 ++++++++++++++++--- .../controller/ll_sw/nordic/lll/lll_adv.c | 12 +++++++---- .../controller/ll_sw/nordic/lll/lll_master.c | 11 ++++++---- .../controller/ll_sw/nordic/lll/lll_scan.c | 14 ++++++++----- .../controller/ll_sw/nordic/lll/lll_slave.c | 11 ++++++---- 5 files changed, 49 insertions(+), 20 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index 8e63540410c..505bb0a3ef6 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -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) { diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c index 2dba421c46d..7cd73a81e80 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c @@ -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 diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_master.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_master.c index f3305327359..14a6c84847e 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_master.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_master.c @@ -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 diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c index c8b37f4c8a8..ad836b068c8 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c @@ -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 diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_slave.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_slave.c index a430a418f0b..f4c260a46a2 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_slave.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_slave.c @@ -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