Bluetooth: controller: split: Refactor to reuse common ISR code

Refactor to reuse common repeated code in ISR that reset
status, and performed abort, done and cleanup.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2020-02-06 16:43:46 +05:30 committed by Carles Cufí
commit bb720d68ce
17 changed files with 191 additions and 304 deletions

View file

@ -438,7 +438,7 @@ endif # BT_CONN
config BT_CTLR_CHAN_SEL_2 config BT_CTLR_CHAN_SEL_2
bool "Channel Selection Algorithm #2" bool "Channel Selection Algorithm #2"
depends on (BT_CONN || BT_CTLR_ADV_EXT) && BT_CTLR_CHAN_SEL_2_SUPPORT depends on (BT_CONN || BT_CTLR_ADV_PERIODIC) && BT_CTLR_CHAN_SEL_2_SUPPORT
default y default y
help help
Enable support for Bluetooth 5.0 LE Channel Selection Algorithm #2 in Enable support for Bluetooth 5.0 LE Channel Selection Algorithm #2 in
@ -448,7 +448,6 @@ config BT_CTLR_ADV_EXT
bool "LE Advertising Extensions" bool "LE Advertising Extensions"
depends on BT_CTLR_ADV_EXT_SUPPORT depends on BT_CTLR_ADV_EXT_SUPPORT
select BT_CTLR_SCAN_REQ_NOTIFY select BT_CTLR_SCAN_REQ_NOTIFY
select BT_CTLR_CHAN_SEL_2
help help
Enable support for Bluetooth 5.0 LE Advertising Extensions in the Enable support for Bluetooth 5.0 LE Advertising Extensions in the
Controller. Controller.
@ -463,6 +462,7 @@ config BT_CTLR_ADV_SET
config BT_CTLR_ADV_PERIODIC config BT_CTLR_ADV_PERIODIC
bool "LE Periodic Advertising" bool "LE Periodic Advertising"
depends on BT_CTLR_ADV_EXT depends on BT_CTLR_ADV_EXT
select BT_CTLR_CHAN_SEL_2
help help
Enable support for Bluetooth 5.0 LE Periodic Advertising in the Enable support for Bluetooth 5.0 LE Periodic Advertising in the
Controller. Controller.

View file

@ -304,18 +304,8 @@ static inline int lll_stop(void *lll)
return ret; return ret;
} }
static inline int lll_is_stop(void *lll)
{
struct lll_hdr *hdr = lll;
return !!hdr->is_stop;
}
int lll_init(void); int lll_init(void);
int lll_reset(void); int lll_reset(void);
int lll_prepare(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb,
lll_prepare_cb_t prepare_cb, int prio,
struct lll_prepare_param *prepare_param);
void lll_resume(void *param); void lll_resume(void *param);
void lll_disable(void *param); void lll_disable(void *param);
uint32_t lll_radio_is_idle(void); uint32_t lll_radio_is_idle(void);

View file

@ -15,12 +15,10 @@
#include <soc.h> #include <soc.h>
#include "hal/debug.h" #include "hal/debug.h"
#if defined(CONFIG_BT_CONN)
static uint8_t chan_sel_remap(uint8_t *chan_map, uint8_t chan_index); static uint8_t chan_sel_remap(uint8_t *chan_map, uint8_t chan_index);
#if defined(CONFIG_BT_CTLR_CHAN_SEL_2) #if defined(CONFIG_BT_CTLR_CHAN_SEL_2)
static uint16_t chan_prn(uint16_t counter, uint16_t chan_id); static uint16_t chan_prn(uint16_t counter, uint16_t chan_id);
#endif /* CONFIG_BT_CTLR_CHAN_SEL_2 */ #endif /* CONFIG_BT_CTLR_CHAN_SEL_2 */
#endif /* CONFIG_BT_CONN */
#if defined(CONFIG_BT_CONN) #if defined(CONFIG_BT_CONN)
uint8_t lll_chan_sel_1(uint8_t *chan_use, uint8_t hop, uint16_t latency, uint8_t *chan_map, uint8_t lll_chan_sel_1(uint8_t *chan_use, uint8_t hop, uint16_t latency, uint8_t *chan_map,
@ -43,6 +41,7 @@ uint8_t lll_chan_sel_1(uint8_t *chan_use, uint8_t hop, uint16_t latency, uint8_t
return chan_next; return chan_next;
} }
#endif /* CONFIG_BT_CONN */
#if defined(CONFIG_BT_CTLR_CHAN_SEL_2) #if defined(CONFIG_BT_CTLR_CHAN_SEL_2)
uint8_t lll_chan_sel_2(uint16_t counter, uint16_t chan_id, uint8_t *chan_map, uint8_t lll_chan_sel_2(uint16_t counter, uint16_t chan_id, uint8_t *chan_map,
@ -168,4 +167,3 @@ static uint16_t chan_prn(uint16_t counter, uint16_t chan_id)
return prn_e; return prn_e;
} }
#endif /* CONFIG_BT_CTLR_CHAN_SEL_2 */ #endif /* CONFIG_BT_CTLR_CHAN_SEL_2 */
#endif /* CONFIG_BT_CONN */

View file

@ -127,12 +127,9 @@ uint8_t lll_conn_sca_local_get(void);
uint32_t lll_conn_ppm_local_get(void); uint32_t lll_conn_ppm_local_get(void);
uint32_t lll_conn_ppm_get(uint8_t sca); uint32_t lll_conn_ppm_get(uint8_t sca);
void lll_conn_prepare_reset(void); void lll_conn_prepare_reset(void);
int lll_conn_is_abort_cb(void *next, int prio, void *curr,
lll_prepare_cb_t *resume_cb, int *resume_prio);
void lll_conn_abort_cb(struct lll_prepare_param *prepare_param, void *param); void lll_conn_abort_cb(struct lll_prepare_param *prepare_param, void *param);
void lll_conn_isr_rx(void *param); void lll_conn_isr_rx(void *param);
void lll_conn_isr_tx(void *param); void lll_conn_isr_tx(void *param);
void lll_conn_isr_abort(void *param);
void lll_conn_rx_pkt_set(struct lll_conn *lll); void lll_conn_rx_pkt_set(struct lll_conn *lll);
void lll_conn_tx_pkt_set(struct lll_conn *lll, struct pdu_data *pdu_data_tx); void lll_conn_tx_pkt_set(struct lll_conn *lll, struct pdu_data *pdu_data_tx);
void lll_conn_pdu_tx_prep(struct lll_conn *lll, struct pdu_data **pdu_data_tx); void lll_conn_pdu_tx_prep(struct lll_conn *lll, struct pdu_data **pdu_data_tx);

View file

@ -56,6 +56,7 @@ static int prepare(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb,
lll_prepare_cb_t prepare_cb, int prio, lll_prepare_cb_t prepare_cb, int prio,
struct lll_prepare_param *prepare_param, uint8_t is_resume); struct lll_prepare_param *prepare_param, uint8_t is_resume);
static int resume_enqueue(lll_prepare_cb_t resume_cb, int resume_prio); static int resume_enqueue(lll_prepare_cb_t resume_cb, int resume_prio);
static void isr_race(void *param);
#if !defined(CONFIG_BT_CTLR_LOW_LAT) #if !defined(CONFIG_BT_CTLR_LOW_LAT)
static void ticker_start_op_cb(uint32_t status, void *param); static void ticker_start_op_cb(uint32_t status, void *param);
@ -305,6 +306,12 @@ bool lll_is_done(void *param)
return !event.curr.abort_cb; return !event.curr.abort_cb;
} }
int lll_is_abort_cb(void *next, int prio, void *curr,
lll_prepare_cb_t *resume_cb, int *resume_prio)
{
return -ECANCELED;
}
uint32_t lll_evt_offset_get(struct evt_hdr *evt) uint32_t lll_evt_offset_get(struct evt_hdr *evt)
{ {
if (0) { if (0) {
@ -391,6 +398,71 @@ int8_t lll_radio_tx_pwr_floor(int8_t tx_pwr_lvl)
return radio_tx_power_floor(tx_pwr_lvl); return radio_tx_power_floor(tx_pwr_lvl);
} }
void lll_isr_tx_status_reset(void)
{
radio_status_reset();
radio_tmr_status_reset();
if (IS_ENABLED(CONFIG_BT_CTLR_GPIO_PA_PIN) ||
IS_ENABLED(CONFIG_BT_CTLR_GPIO_LNA_PIN)) {
radio_gpio_pa_lna_disable();
}
}
void lll_isr_rx_status_reset(void)
{
radio_status_reset();
radio_tmr_status_reset();
radio_rssi_status_reset();
if (IS_ENABLED(CONFIG_BT_CTLR_GPIO_PA_PIN) ||
IS_ENABLED(CONFIG_BT_CTLR_GPIO_LNA_PIN)) {
radio_gpio_pa_lna_disable();
}
}
void lll_isr_status_reset(void)
{
radio_status_reset();
radio_tmr_status_reset();
radio_filter_status_reset();
radio_ar_status_reset();
radio_rssi_status_reset();
if (IS_ENABLED(CONFIG_BT_CTLR_GPIO_PA_PIN) ||
IS_ENABLED(CONFIG_BT_CTLR_GPIO_LNA_PIN)) {
radio_gpio_pa_lna_disable();
}
}
inline void lll_isr_abort(void *param)
{
lll_isr_status_reset();
lll_isr_cleanup(param);
}
void lll_isr_done(void *param)
{
lll_isr_abort(param);
}
void lll_isr_cleanup(void *param)
{
int err;
radio_isr_set(isr_race, param);
if (!radio_is_idle()) {
radio_disable();
}
radio_tmr_stop();
err = lll_hfclock_off();
LL_ASSERT(!err || err == -EBUSY);
lll_done(NULL);
}
static int init_reset(void) static int init_reset(void)
{ {
return 0; return 0;
@ -494,6 +566,12 @@ static int resume_enqueue(lll_prepare_cb_t resume_cb, int resume_prio)
&prepare_param, resume_cb, resume_prio, 1); &prepare_param, resume_cb, resume_prio, 1);
} }
static void isr_race(void *param)
{
/* NOTE: lll_disable could have a race with ... */
radio_status_reset();
}
#if !defined(CONFIG_BT_CTLR_LOW_LAT) #if !defined(CONFIG_BT_CTLR_LOW_LAT)
static void ticker_start_op_cb(uint32_t status, void *param) static void ticker_start_op_cb(uint32_t status, void *param)
{ {

View file

@ -53,8 +53,6 @@ static void isr_tx(void *param);
static void isr_rx(void *param); static void isr_rx(void *param);
static void isr_done(void *param); static void isr_done(void *param);
static void isr_abort(void *param); static void isr_abort(void *param);
static void isr_cleanup(void *param);
static void isr_race(void *param);
static struct pdu_adv *chan_prepare(struct lll_adv *lll); static struct pdu_adv *chan_prepare(struct lll_adv *lll);
#if defined(CONFIG_BT_CTLR_ADV_EXT) #if defined(CONFIG_BT_CTLR_ADV_EXT)
@ -335,20 +333,12 @@ static void isr_tx(void *param)
{ {
uint32_t hcto; uint32_t hcto;
/* TODO: MOVE to a common interface, isr_lll_radio_status? */
if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) { if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
lll_prof_latency_capture(); lll_prof_latency_capture();
} }
/* Clear radio status and events */ /* Clear radio tx status and events */
radio_status_reset(); lll_isr_tx_status_reset();
radio_tmr_status_reset();
if (IS_ENABLED(CONFIG_BT_CTLR_GPIO_PA_PIN) ||
IS_ENABLED(CONFIG_BT_CTLR_GPIO_LNA_PIN)) {
radio_gpio_pa_lna_disable();
}
/* TODO: MOVE ^^ */
/* setup tIFS switching */ /* setup tIFS switching */
radio_tmr_tifs_set(EVENT_IFS_US); radio_tmr_tifs_set(EVENT_IFS_US);
@ -440,17 +430,9 @@ static void isr_rx(void *param)
} }
/* Clear radio status and events */ /* Clear radio status and events */
radio_status_reset(); lll_isr_status_reset();
radio_tmr_status_reset();
radio_filter_status_reset();
radio_ar_status_reset();
radio_rssi_status_reset();
if (IS_ENABLED(CONFIG_BT_CTLR_GPIO_PA_PIN) ||
IS_ENABLED(CONFIG_BT_CTLR_GPIO_LNA_PIN)) {
radio_gpio_pa_lna_disable();
}
/* No Rx */
if (!trx_done) { if (!trx_done) {
goto isr_rx_do_close; goto isr_rx_do_close;
} }
@ -479,19 +461,8 @@ static void isr_done(void *param)
struct node_rx_hdr *node_rx; struct node_rx_hdr *node_rx;
struct lll_adv *lll = param; struct lll_adv *lll = param;
/* TODO: MOVE to a common interface, isr_lll_radio_status? */
/* Clear radio status and events */ /* Clear radio status and events */
radio_status_reset(); lll_isr_status_reset();
radio_tmr_status_reset();
radio_filter_status_reset();
radio_ar_status_reset();
radio_rssi_status_reset();
if (IS_ENABLED(CONFIG_BT_CTLR_GPIO_PA_PIN) ||
IS_ENABLED(CONFIG_BT_CTLR_GPIO_LNA_PIN)) {
radio_gpio_pa_lna_disable();
}
/* TODO: MOVE ^^ */
#if defined(CONFIG_BT_HCI_MESH_EXT) #if defined(CONFIG_BT_HCI_MESH_EXT)
if (_radio.advertiser.is_mesh && if (_radio.advertiser.is_mesh &&
@ -594,49 +565,17 @@ static void isr_done(void *param)
ARG_UNUSED(node_rx); ARG_UNUSED(node_rx);
#endif /* !CONFIG_BT_CTLR_ADV_INDICATION */ #endif /* !CONFIG_BT_CTLR_ADV_INDICATION */
isr_cleanup(param); lll_isr_cleanup(param);
} }
static void isr_abort(void *param) static void isr_abort(void *param)
{ {
/* Clear radio status and events */ /* Clear radio status and events */
radio_status_reset(); lll_isr_status_reset();
radio_tmr_status_reset();
radio_filter_status_reset();
radio_ar_status_reset();
radio_rssi_status_reset();
if (IS_ENABLED(CONFIG_BT_CTLR_GPIO_PA_PIN) ||
IS_ENABLED(CONFIG_BT_CTLR_GPIO_LNA_PIN)) {
radio_gpio_pa_lna_disable();
}
radio_filter_disable(); radio_filter_disable();
isr_cleanup(param); lll_isr_cleanup(param);
}
static void isr_cleanup(void *param)
{
int err;
radio_isr_set(isr_race, param);
if (!radio_is_idle()) {
radio_disable();
}
radio_tmr_stop();
err = lll_hfclock_off();
LL_ASSERT(!err || err == -EBUSY);
lll_done(NULL);
}
static void isr_race(void *param)
{
/* NOTE: lll_disable could have a race with ... */
radio_status_reset();
} }
static struct pdu_adv *chan_prepare(struct lll_adv *lll) static struct pdu_adv *chan_prepare(struct lll_adv *lll)

View file

@ -19,6 +19,14 @@ struct lll_adv_sync {
uint8_t access_addr[4]; uint8_t access_addr[4];
uint8_t crc_init[3]; uint8_t crc_init[3];
uint16_t latency_prepare;
uint16_t latency_event;
uint16_t event_counter;
uint8_t data_chan_map[5];
uint8_t data_chan_count:6;
uint16_t data_chan_id;
struct lll_adv_pdu data; struct lll_adv_pdu data;
}; };

View file

@ -31,10 +31,6 @@
#include <soc.h> #include <soc.h>
#include "hal/debug.h" #include "hal/debug.h"
static void isr_done(void *param);
static void isr_cleanup(void *param);
static void isr_race(void *param);
void lll_adv_aux_prepare(struct lll_adv *lll) void lll_adv_aux_prepare(struct lll_adv *lll)
{ {
struct pdu_adv_com_ext_adv *p; struct pdu_adv_com_ext_adv *p;
@ -72,7 +68,7 @@ void lll_adv_aux_prepare(struct lll_adv *lll)
lll_chan_set(aux->chan_idx); lll_chan_set(aux->chan_idx);
/* TODO: Based on adv_mode switch to Rx, if needed */ /* TODO: Based on adv_mode switch to Rx, if needed */
radio_isr_set(isr_done, lll); radio_isr_set(lll_isr_done, lll);
radio_switch_complete_and_disable(); radio_switch_complete_and_disable();
start_us = 1000; start_us = 1000;
@ -88,41 +84,3 @@ void lll_adv_aux_prepare(struct lll_adv *lll)
CONFIG_BT_CTLR_GPIO_PA_OFFSET); CONFIG_BT_CTLR_GPIO_PA_OFFSET);
#endif /* !CONFIG_BT_CTLR_GPIO_PA_PIN */ #endif /* !CONFIG_BT_CTLR_GPIO_PA_PIN */
} }
static void isr_done(void *param)
{
/* TODO: MOVE to a common interface, isr_lll_radio_status? */
/* Clear radio status and events */
radio_status_reset();
radio_tmr_status_reset();
radio_filter_status_reset();
radio_ar_status_reset();
radio_rssi_status_reset();
if (IS_ENABLED(CONFIG_BT_CTLR_GPIO_PA_PIN) ||
IS_ENABLED(CONFIG_BT_CTLR_GPIO_LNA_PIN)) {
radio_gpio_pa_lna_disable();
}
/* TODO: MOVE ^^ */
isr_cleanup(param);
}
static void isr_cleanup(void *param)
{
int err;
radio_isr_set(isr_race, param);
radio_tmr_stop();
err = lll_hfclock_off();
LL_ASSERT(!err || err == -EBUSY);
lll_done(NULL);
}
static void isr_race(void *param)
{
/* NOTE: lll_disable could have a race with ... */
radio_status_reset();
}

View file

@ -14,6 +14,7 @@
#include "hal/radio.h" #include "hal/radio.h"
#include "hal/ticker.h" #include "hal/ticker.h"
#include "util/util.h"
#include "util/memq.h" #include "util/memq.h"
#include "pdu.h" #include "pdu.h"
@ -22,19 +23,22 @@
#include "lll_vendor.h" #include "lll_vendor.h"
#include "lll_clock.h" #include "lll_clock.h"
#include "lll_chan.h" #include "lll_chan.h"
#include "lll_adv.h"
#include "lll_adv_sync.h" #include "lll_adv_sync.h"
#include "lll_internal.h" #include "lll_internal.h"
#include "lll_adv_internal.h"
#include "lll_tim_internal.h" #include "lll_tim_internal.h"
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER) #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
#define LOG_MODULE_NAME bt_ctlr_lll_master #define LOG_MODULE_NAME bt_ctlr_lll_adv_sync
#include "common/log.h" #include "common/log.h"
#include <soc.h> #include <soc.h>
#include "hal/debug.h" #include "hal/debug.h"
static int init_reset(void); static int init_reset(void);
static int prepare_cb(struct lll_prepare_param *prepare_param); static int prepare_cb(struct lll_prepare_param *prepare_param);
static void abort_cb(struct lll_prepare_param *prepare_param, void *param);
int lll_adv_sync_init(void) int lll_adv_sync_init(void)
{ {
@ -68,8 +72,7 @@ void lll_adv_sync_prepare(void *param)
err = lll_hfclock_on(); err = lll_hfclock_on();
LL_ASSERT(!err || err == -EINPROGRESS); LL_ASSERT(!err || err == -EINPROGRESS);
err = lll_prepare(lll_conn_is_abort_cb, lll_conn_abort_cb, prepare_cb, err = lll_prepare(lll_is_abort_cb, abort_cb, prepare_cb, 0, p);
0, p);
LL_ASSERT(!err || err == -EINPROGRESS); LL_ASSERT(!err || err == -EINPROGRESS);
} }
@ -82,12 +85,14 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
{ {
struct lll_adv_sync *lll = prepare_param->param; struct lll_adv_sync *lll = prepare_param->param;
uint32_t ticks_at_event, ticks_at_start; uint32_t ticks_at_event, ticks_at_start;
struct pdu_adv *pdu;
struct evt_hdr *evt; struct evt_hdr *evt;
uint16_t event_counter; uint16_t event_counter;
uint32_t remainder_us; uint32_t remainder_us;
uint8_t data_chan_use; uint8_t data_chan_use;
uint32_t remainder; uint32_t remainder;
uint16_t lazy; uint16_t lazy;
uint8_t upd;
DEBUG_RADIO_START_A(1); DEBUG_RADIO_START_A(1);
@ -102,12 +107,8 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
/* store the next event counter value */ /* store the next event counter value */
lll->event_counter = event_counter + 1; lll->event_counter = event_counter + 1;
/* TODO: Do the above in ULL ? */ /* TODO: Do the above in ULL ? */
/* Reset connection event global variables */
lll_conn_prepare_reset();
/* TODO: can we do something in ULL? */ /* TODO: can we do something in ULL? */
lll->latency_event = lll->latency_prepare; lll->latency_event = lll->latency_prepare;
lll->latency_prepare = 0; lll->latency_prepare = 0;
@ -132,18 +133,12 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
((uint32_t)lll->crc_init[0]))); ((uint32_t)lll->crc_init[0])));
lll_chan_set(data_chan_use); lll_chan_set(data_chan_use);
/* setup the radio tx packet buffer */ pdu = lll_adv_sync_data_latest_get(lll, &upd);
lll_conn_tx_pkt_set(lll, pdu_data_tx); radio_pkt_tx_set(pdu);
radio_isr_set(lll_conn_isr_tx, lll); /* TODO: chaining */
radio_isr_set(lll_isr_done, lll);
radio_tmr_tifs_set(EVENT_IFS_US); radio_switch_complete_and_disable();
#if defined(CONFIG_BT_CTLR_PHY)
radio_switch_complete_and_rx(lll->phy_rx);
#else /* !CONFIG_BT_CTLR_PHY */
radio_switch_complete_and_rx(0);
#endif /* !CONFIG_BT_CTLR_PHY */
ticks_at_event = prepare_param->ticks_at_expire; ticks_at_event = prepare_param->ticks_at_expire;
evt = HDR_LLL2EVT(lll); evt = HDR_LLL2EVT(lll);
@ -155,9 +150,6 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
remainder = prepare_param->remainder; remainder = prepare_param->remainder;
remainder_us = radio_tmr_start(1, ticks_at_start, 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();
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN) #if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
radio_gpio_pa_setup(); radio_gpio_pa_setup();
@ -178,9 +170,10 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
#if defined(CONFIG_BT_CTLR_XTAL_ADVANCED) && \ #if defined(CONFIG_BT_CTLR_XTAL_ADVANCED) && \
(EVENT_OVERHEAD_PREEMPT_US <= EVENT_OVERHEAD_PREEMPT_MIN_US) (EVENT_OVERHEAD_PREEMPT_US <= EVENT_OVERHEAD_PREEMPT_MIN_US)
/* check if preempt to start has changed */ /* 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_ADV_SYNC_BASE +
ull_adv_sync_lll_handle_get(lll)),
ticks_at_event)) { ticks_at_event)) {
radio_isr_set(lll_conn_isr_abort, lll); radio_isr_set(lll_isr_abort, lll);
radio_disable(); radio_disable();
} else } else
#endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */ #endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */
@ -191,7 +184,31 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
LL_ASSERT(!ret); LL_ASSERT(!ret);
} }
DEBUG_RADIO_START_M(1); DEBUG_RADIO_START_A(1);
return 0; return 0;
} }
static void abort_cb(struct lll_prepare_param *prepare_param, void *param)
{
int err;
/* NOTE: This is not a prepare being cancelled */
if (!prepare_param) {
/* Perform event abort here.
* After event has been cleanly aborted, clean up resources
* and dispatch event done.
*/
radio_isr_set(lll_isr_done, param);
radio_disable();
return;
}
/* NOTE: Else clean the top half preparations of the aborted event
* currently in preparation pipeline.
*/
err = lll_hfclock_off();
LL_ASSERT(!err || err == -EBUSY);
lll_done(param);
}

View file

@ -7,3 +7,5 @@
int lll_adv_sync_init(void); int lll_adv_sync_init(void);
int lll_adv_sync_reset(void); int lll_adv_sync_reset(void);
void lll_adv_sync_prepare(void *param); void lll_adv_sync_prepare(void *param);
extern uint16_t ull_adv_sync_lll_handle_get(struct lll_adv_sync *lll);

View file

@ -37,8 +37,6 @@
static int init_reset(void); static int init_reset(void);
static void isr_done(void *param); static void isr_done(void *param);
static void isr_cleanup(void *param);
static void isr_race(void *param);
static int isr_rx_pdu(struct lll_conn *lll, struct pdu_data *pdu_data_rx, static int isr_rx_pdu(struct lll_conn *lll, struct pdu_data *pdu_data_rx,
struct node_tx **tx_release, uint8_t *is_rx_enqueue); struct node_tx **tx_release, uint8_t *is_rx_enqueue);
static struct pdu_data *empty_tx_enqueue(struct lll_conn *lll); static struct pdu_data *empty_tx_enqueue(struct lll_conn *lll);
@ -102,12 +100,6 @@ void lll_conn_prepare_reset(void)
#endif /* CONFIG_BT_CTLR_LE_ENC */ #endif /* CONFIG_BT_CTLR_LE_ENC */
} }
int lll_conn_is_abort_cb(void *next, int prio, void *curr,
lll_prepare_cb_t *resume_cb, int *resume_prio)
{
return -ECANCELED;
}
void lll_conn_abort_cb(struct lll_prepare_param *prepare_param, void *param) void lll_conn_abort_cb(struct lll_prepare_param *prepare_param, void *param)
{ {
int err; int err;
@ -161,16 +153,10 @@ void lll_conn_isr_rx(void *param)
crc_ok = rssi_ready = 0U; crc_ok = rssi_ready = 0U;
} }
/* Clear radio status and events */ /* Clear radio rx status and events */
radio_status_reset(); lll_isr_rx_status_reset();
radio_tmr_status_reset();
radio_rssi_status_reset();
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN) || \
defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
radio_gpio_pa_lna_disable();
#endif /* CONFIG_BT_CTLR_GPIO_PA_PIN || CONFIG_BT_CTLR_GPIO_LNA_PIN */
/* No Rx */
if (!trx_done) { if (!trx_done) {
radio_isr_set(isr_done, param); radio_isr_set(isr_done, param);
radio_disable(); radio_disable();
@ -367,16 +353,8 @@ void lll_conn_isr_tx(void *param)
struct lll_conn *lll = (void *)param; struct lll_conn *lll = (void *)param;
uint32_t hcto; uint32_t hcto;
/* TODO: MOVE to a common interface, isr_lll_radio_status? */ /* Clear radio tx status and events */
/* Clear radio status and events */ lll_isr_tx_status_reset();
radio_status_reset();
radio_tmr_status_reset();
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN) || \
defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
radio_gpio_pa_lna_disable();
#endif /* CONFIG_BT_CTLR_GPIO_PA_PIN || CONFIG_BT_CTLR_GPIO_LNA_PIN */
/* TODO: MOVE ^^ */
/* setup tIFS switching */ /* setup tIFS switching */
radio_tmr_tifs_set(EVENT_IFS_US); radio_tmr_tifs_set(EVENT_IFS_US);
@ -436,23 +414,6 @@ void lll_conn_isr_tx(void *param)
radio_isr_set(lll_conn_isr_rx, param); radio_isr_set(lll_conn_isr_rx, param);
} }
void lll_conn_isr_abort(void *param)
{
/* Clear radio status and events */
radio_status_reset();
radio_tmr_status_reset();
radio_filter_status_reset();
radio_ar_status_reset();
radio_rssi_status_reset();
if (IS_ENABLED(CONFIG_BT_CTLR_GPIO_PA_PIN) ||
IS_ENABLED(CONFIG_BT_CTLR_GPIO_LNA_PIN)) {
radio_gpio_pa_lna_disable();
}
isr_cleanup(param);
}
void lll_conn_rx_pkt_set(struct lll_conn *lll) void lll_conn_rx_pkt_set(struct lll_conn *lll)
{ {
struct node_rx_pdu *node_rx; struct node_rx_pdu *node_rx;
@ -595,19 +556,7 @@ static void isr_done(void *param)
{ {
struct event_done_extra *e; struct event_done_extra *e;
/* TODO: MOVE to a common interface, isr_lll_radio_status? */ lll_isr_status_reset();
/* Clear radio status and events */
radio_status_reset();
radio_tmr_status_reset();
radio_filter_status_reset();
radio_ar_status_reset();
radio_rssi_status_reset();
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN) || \
defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
radio_gpio_pa_lna_disable();
#endif /* CONFIG_BT_CTLR_GPIO_PA_PIN || CONFIG_BT_CTLR_GPIO_LNA_PIN */
/* TODO: MOVE ^^ */
e = ull_event_done_extra_get(); e = ull_event_done_extra_get();
LL_ASSERT(e); LL_ASSERT(e);
@ -648,30 +597,7 @@ static void isr_done(void *param)
} }
#endif /* CONFIG_BT_PERIPHERAL */ #endif /* CONFIG_BT_PERIPHERAL */
isr_cleanup(param); lll_isr_cleanup(param);
}
static void isr_cleanup(void *param)
{
int err;
radio_isr_set(isr_race, param);
if (!radio_is_idle()) {
radio_disable();
}
radio_tmr_stop();
err = lll_hfclock_off();
LL_ASSERT(!err || err == -EBUSY);
lll_done(NULL);
}
static void isr_race(void *param)
{
/* NOTE: lll_disable could have a race with ... */
radio_status_reset();
} }
static inline bool ctrl_pdu_len_check(uint8_t len) static inline bool ctrl_pdu_len_check(uint8_t len)

View file

@ -4,11 +4,29 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
int lll_prepare(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb,
lll_prepare_cb_t prepare_cb, int prio,
struct lll_prepare_param *prepare_param);
int lll_prepare_done(void *param); int lll_prepare_done(void *param);
int lll_done(void *param); int lll_done(void *param);
bool lll_is_done(void *param); bool lll_is_done(void *param);
int lll_is_abort_cb(void *next, int prio, void *curr,
lll_prepare_cb_t *resume_cb, int *resume_prio);
static inline int lll_is_stop(void *lll)
{
struct lll_hdr *hdr = lll;
return !!hdr->is_stop;
}
uint32_t lll_evt_offset_get(struct evt_hdr *evt); uint32_t lll_evt_offset_get(struct evt_hdr *evt);
uint32_t lll_preempt_calc(struct evt_hdr *evt, uint8_t ticker_id, uint32_t lll_preempt_calc(struct evt_hdr *evt, uint8_t ticker_id,
uint32_t ticks_at_event); uint32_t ticks_at_event);
void lll_chan_set(uint32_t chan); void lll_chan_set(uint32_t chan);
uint8_t lll_entropy_get(uint8_t len, void *rand); uint8_t lll_entropy_get(uint8_t len, void *rand);
void lll_isr_tx_status_reset(void);
void lll_isr_rx_status_reset(void);
void lll_isr_status_reset(void);
void lll_isr_abort(void *param);
void lll_isr_done(void *param);
void lll_isr_cleanup(void *param);

View file

@ -78,7 +78,7 @@ void lll_master_prepare(void *param)
lll->latency_prepare += elapsed; lll->latency_prepare += elapsed;
/* Invoke common pipeline handling of prepare */ /* Invoke common pipeline handling of prepare */
err = lll_prepare(lll_conn_is_abort_cb, lll_conn_abort_cb, prepare_cb, err = lll_prepare(lll_is_abort_cb, lll_conn_abort_cb, prepare_cb,
0, p); 0, p);
LL_ASSERT(!err || err == -EINPROGRESS); LL_ASSERT(!err || err == -EINPROGRESS);
} }
@ -201,7 +201,7 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
/* check if preempt to start has changed */ /* 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_CONN_BASE + lll->handle),
ticks_at_event)) { ticks_at_event)) {
radio_isr_set(lll_conn_isr_abort, lll); radio_isr_set(lll_isr_abort, lll);
radio_disable(); radio_disable();
} else } else
#endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */ #endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */

View file

@ -55,7 +55,6 @@ static void isr_done(void *param);
static void isr_window(void *param); static void isr_window(void *param);
static void isr_abort(void *param); static void isr_abort(void *param);
static void isr_cleanup(void *param); static void isr_cleanup(void *param);
static void isr_race(void *param);
static inline bool isr_rx_scan_check(struct lll_scan *lll, uint8_t irkmatch_ok, static inline bool isr_rx_scan_check(struct lll_scan *lll, uint8_t irkmatch_ok,
uint8_t devmatch_ok, uint8_t rl_idx); uint8_t devmatch_ok, uint8_t rl_idx);
@ -404,17 +403,9 @@ static void isr_rx(void *param)
} }
/* Clear radio status and events */ /* Clear radio status and events */
radio_status_reset(); lll_isr_status_reset();
radio_tmr_status_reset();
radio_filter_status_reset();
radio_ar_status_reset();
radio_rssi_status_reset();
if (IS_ENABLED(CONFIG_BT_CTLR_GPIO_PA_PIN) ||
IS_ENABLED(CONFIG_BT_CTLR_GPIO_LNA_PIN)) {
radio_gpio_pa_lna_disable();
}
/* No Rx */
if (!trx_done) { if (!trx_done) {
goto isr_rx_do_close; goto isr_rx_do_close;
} }
@ -453,16 +444,8 @@ static void isr_tx(void *param)
struct node_rx_pdu *node_rx; struct node_rx_pdu *node_rx;
uint32_t hcto; uint32_t hcto;
/* TODO: MOVE to a common interface, isr_lll_radio_status? */
/* Clear radio status and events */ /* Clear radio status and events */
radio_status_reset(); lll_isr_tx_status_reset();
radio_tmr_status_reset();
if (IS_ENABLED(CONFIG_BT_CTLR_GPIO_PA_PIN) ||
IS_ENABLED(CONFIG_BT_CTLR_GPIO_LNA_PIN)) {
radio_gpio_pa_lna_disable();
}
/* TODO: MOVE ^^ */
/* setup tIFS switching */ /* setup tIFS switching */
radio_tmr_tifs_set(EVENT_IFS_US); radio_tmr_tifs_set(EVENT_IFS_US);
@ -507,19 +490,8 @@ static void isr_common_done(void *param)
{ {
struct node_rx_pdu *node_rx; struct node_rx_pdu *node_rx;
/* TODO: MOVE to a common interface, isr_lll_radio_status? */
/* Clear radio status and events */ /* Clear radio status and events */
radio_status_reset(); lll_isr_status_reset();
radio_tmr_status_reset();
radio_filter_status_reset();
radio_ar_status_reset();
radio_rssi_status_reset();
if (IS_ENABLED(CONFIG_BT_CTLR_GPIO_PA_PIN) ||
IS_ENABLED(CONFIG_BT_CTLR_GPIO_LNA_PIN)) {
radio_gpio_pa_lna_disable();
}
/* TODO: MOVE ^^ */
/* setup tIFS switching */ /* setup tIFS switching */
radio_tmr_tifs_set(EVENT_IFS_US); radio_tmr_tifs_set(EVENT_IFS_US);
@ -595,16 +567,7 @@ static void isr_window(void *param)
static void isr_abort(void *param) static void isr_abort(void *param)
{ {
/* Clear radio status and events */ /* Clear radio status and events */
radio_status_reset(); lll_isr_status_reset();
radio_tmr_status_reset();
radio_filter_status_reset();
radio_ar_status_reset();
radio_rssi_status_reset();
if (IS_ENABLED(CONFIG_BT_CTLR_GPIO_PA_PIN) ||
IS_ENABLED(CONFIG_BT_CTLR_GPIO_LNA_PIN)) {
radio_gpio_pa_lna_disable();
}
/* Scanner stop can expire while here in this ISR. /* Scanner stop can expire while here in this ISR.
* Deferred attempt to stop can fail as it would have * Deferred attempt to stop can fail as it would have
@ -623,7 +586,6 @@ static void isr_cleanup(void *param)
{ {
struct lll_scan *lll = param; struct lll_scan *lll = param;
struct node_rx_hdr *node_rx; struct node_rx_hdr *node_rx;
int err;
if (lll_is_done(param)) { if (lll_is_done(param)) {
return; return;
@ -657,23 +619,7 @@ static void isr_cleanup(void *param)
ARG_UNUSED(node_rx); ARG_UNUSED(node_rx);
#endif /* !CONFIG_BT_CTLR_SCAN_INDICATION */ #endif /* !CONFIG_BT_CTLR_SCAN_INDICATION */
radio_isr_set(isr_race, param); lll_isr_cleanup(param);
if (!radio_is_idle()) {
radio_disable();
}
radio_tmr_stop();
err = lll_hfclock_off();
LL_ASSERT(!err || err == -EBUSY);
lll_done(NULL);
}
static void isr_race(void *param)
{
/* NOTE: lll_disable could have a race with ... */
radio_status_reset();
} }
static inline bool isr_rx_scan_check(struct lll_scan *lll, uint8_t irkmatch_ok, static inline bool isr_rx_scan_check(struct lll_scan *lll, uint8_t irkmatch_ok,

View file

@ -243,7 +243,7 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
/* check if preempt to start has changed */ /* 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_CONN_BASE + lll->handle),
ticks_at_event)) { ticks_at_event)) {
radio_isr_set(lll_conn_isr_abort, lll); radio_isr_set(lll_isr_abort, lll);
radio_disable(); radio_disable();
} else } else
#endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */ #endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */

View file

@ -1049,9 +1049,11 @@ int ull_adv_init(void)
{ {
int err; int err;
err = ull_adv_sync_init(); if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC)) {
if (err) { err = ull_adv_sync_init();
return err; if (err) {
return err;
}
} }
err = init_reset(); err = init_reset();
@ -1067,9 +1069,11 @@ int ull_adv_reset(void)
uint8_t handle; uint8_t handle;
int err; int err;
err = ull_adv_sync_reset(); if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC)) {
if (err) { err = ull_adv_sync_reset();
return err; if (err) {
return err;
}
} }
for (handle = 0U; handle < BT_CTLR_ADV_MAX; handle++) { for (handle = 0U; handle < BT_CTLR_ADV_MAX; handle++) {

View file

@ -21,6 +21,7 @@
#include "lll.h" #include "lll.h"
#include "lll_vendor.h" #include "lll_vendor.h"
#include "lll_adv.h" #include "lll_adv.h"
#include "lll_adv_sync.h"
#include "ull_adv_types.h" #include "ull_adv_types.h"
@ -162,6 +163,11 @@ int ull_adv_sync_reset(void)
return 0; return 0;
} }
uint16_t ull_adv_sync_lll_handle_get(struct lll_adv_sync *lll)
{
return sync_handle_get((void *)lll->hdr.parent);
}
uint32_t ull_adv_sync_start(struct ll_adv_sync_set *sync, uint32_t ticks_anchor, uint32_t ull_adv_sync_start(struct ll_adv_sync_set *sync, uint32_t ticks_anchor,
uint32_t volatile *ret_cb) uint32_t volatile *ret_cb)
{ {