Bluetooth: Controller: Extended Advertising back-to-back chaining

Add LLL implementation to chain Extended Advertising PDUs
back-to-back.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2021-10-12 15:19:38 +05:30 committed by Christopher Friedt
commit c5eab2011f
5 changed files with 110 additions and 3 deletions

View file

@ -176,6 +176,22 @@ config BT_CTLR_ADV_PDU_LINK
is required to enable advertising data trains (i.e. transmission of is required to enable advertising data trains (i.e. transmission of
AUX_CHAIN_IND). AUX_CHAIN_IND).
config BT_CTLR_ADV_PDU_BACK2BACK
bool "Enable back-to-back transmission of extended advertising trains"
depends on BT_CTLR_ADV_EXT && BT_BROADCASTER
select BT_CTLR_ADV_PDU_LINK
help
Enables transmission of AUX_CHAIN_IND in extended advertising train by
sending each AUX_CHAIN_IND one after another back-to-back.
config BT_CTLR_ADV_PDU_BACK2BACK_AFS
int "AUX Frame Space for back-to-back transmission of extended advertising trains"
depends on BT_CTLR_ADV_PDU_BACK2BACK
range 300 1000
help
Specific AUX Frame Space to be used for back-to-back transmission of
extended advertising trains. Time specified in microseconds.
config BT_CTLR_ADV_SYNC_PDU_BACK2BACK config BT_CTLR_ADV_SYNC_PDU_BACK2BACK
bool "Enable back-to-back transmission of periodic advertising trains" bool "Enable back-to-back transmission of periodic advertising trains"
depends on BT_CTLR_ADV_PERIODIC depends on BT_CTLR_ADV_PERIODIC

View file

@ -67,6 +67,9 @@ struct lll_adv_aux {
uint32_t ticks_offset; uint32_t ticks_offset;
struct lll_adv_pdu data; struct lll_adv_pdu data;
#if defined(CONFIG_BT_CTLR_ADV_PDU_LINK)
struct pdu_adv *last_pdu;
#endif /* CONFIG_BT_CTLR_ADV_PDU_LINK */
#if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL) #if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL)
int8_t tx_pwr_lvl; int8_t tx_pwr_lvl;

View file

@ -46,7 +46,10 @@
static int init_reset(void); static int init_reset(void);
static int prepare_cb(struct lll_prepare_param *p); static int prepare_cb(struct lll_prepare_param *p);
static void isr_done(void *param); static void isr_done(void *param);
static void isr_tx(void *param); #if defined(CONFIG_BT_CTLR_ADV_PDU_BACK2BACK)
static void isr_tx_chain(void *param);
#endif /* CONFIG_BT_CTLR_ADV_PDU_BACK2BACK */
static void isr_tx_rx(void *param);
static void isr_rx(void *param); static void isr_rx(void *param);
static inline int isr_rx_pdu(struct lll_adv_aux *lll_aux, static inline int isr_rx_pdu(struct lll_adv_aux *lll_aux,
uint8_t devmatch_ok, uint8_t devmatch_id, uint8_t devmatch_ok, uint8_t devmatch_id,
@ -224,9 +227,21 @@ static int prepare_cb(struct lll_prepare_param *p)
ARG_UNUSED(upd); ARG_UNUSED(upd);
#endif /* !CONFIG_BT_CTLR_PRIVACY */ #endif /* !CONFIG_BT_CTLR_PRIVACY */
radio_isr_set(isr_tx, lll); radio_isr_set(isr_tx_rx, lll);
radio_tmr_tifs_set(EVENT_IFS_US); radio_tmr_tifs_set(EVENT_IFS_US);
radio_switch_complete_and_rx(phy_s); radio_switch_complete_and_rx(phy_s);
#if defined(CONFIG_BT_CTLR_ADV_PDU_BACK2BACK)
} else if (sec_pdu->adv_ext_ind.ext_hdr_len &&
sec_pdu->adv_ext_ind.ext_hdr.aux_ptr) {
lll->last_pdu = sec_pdu;
radio_isr_set(isr_tx_chain, lll);
radio_tmr_tifs_set(EVENT_B2B_MAFS_US);
radio_switch_complete_and_b2b_tx(phy_s, lll_adv->phy_flags,
phy_s, lll_adv->phy_flags);
#endif /* CONFIG_BT_CTLR_ADV_PDU_BACK2BACK */
} else { } else {
radio_isr_set(isr_done, lll); radio_isr_set(isr_done, lll);
radio_switch_complete_and_disable(); radio_switch_complete_and_disable();
@ -290,7 +305,77 @@ static void isr_done(void *param)
lll_isr_cleanup(param); lll_isr_cleanup(param);
} }
static void isr_tx(void *param) #if defined(CONFIG_BT_CTLR_ADV_PDU_BACK2BACK)
static void isr_tx_chain(void *param)
{
struct lll_adv_aux *lll_aux;
struct lll_adv *lll;
struct pdu_adv *pdu;
if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
lll_prof_latency_capture();
}
/* Clear radio tx status and events */
lll_isr_tx_status_reset();
lll_aux = param;
lll = lll_aux->adv;
/* FIXME: Use implementation defined channel index */
lll_chan_set(0);
pdu = lll_adv_pdu_linked_next_get(lll_aux->last_pdu);
LL_ASSERT(pdu);
lll_aux->last_pdu = pdu;
/* setup tIFS switching */
if (pdu->adv_ext_ind.ext_hdr_len && pdu->adv_ext_ind.ext_hdr.aux_ptr) {
radio_isr_set(isr_tx_chain, lll_aux);
radio_tmr_tifs_set(EVENT_B2B_MAFS_US);
radio_switch_complete_and_b2b_tx(lll->phy_s, lll->phy_flags,
lll->phy_s, lll->phy_flags);
} else {
radio_isr_set(isr_done, lll_aux);
radio_switch_complete_and_disable();
}
radio_pkt_tx_set(pdu);
/* assert if radio packet ptr is not set and radio started rx */
LL_ASSERT(!radio_is_ready());
if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
lll_prof_cputime_capture();
}
/* capture end of AUX_SYNC_IND/AUX_CHAIN_IND PDU, used for calculating
* next PDU timestamp.
*/
radio_tmr_end_capture();
#if defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
/* PA/LNA enable is overwriting packet end used in ISR
* profiling, hence back it up for later use.
*/
lll_prof_radio_end_backup();
}
radio_gpio_lna_setup();
radio_gpio_pa_lna_enable(radio_tmr_tifs_base_get() + EVENT_B2B_MAFS_US -
4 - radio_tx_chain_delay_get(lll->phy_s,
lll->phy_flags) -
CONFIG_BT_CTLR_GPIO_LNA_OFFSET);
#endif /* CONFIG_BT_CTLR_GPIO_LNA_PIN */
if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
lll_prof_send();
}
}
#endif /* CONFIG_BT_CTLR_ADV_PDU_BACK2BACK */
static void isr_tx_rx(void *param)
{ {
struct node_rx_pdu *node_rx_prof; struct node_rx_pdu *node_rx_prof;
struct node_rx_pdu *node_rx; struct node_rx_pdu *node_rx;

View file

@ -93,6 +93,8 @@
#define EVENT_MAFS_US 300 #define EVENT_MAFS_US 300
/* Standard allows 2 us timing uncertainty inside the event */ /* Standard allows 2 us timing uncertainty inside the event */
#define EVENT_MAFS_MAX_US (EVENT_MAFS_US + EVENT_CLOCK_JITTER_US) #define EVENT_MAFS_MAX_US (EVENT_MAFS_US + EVENT_CLOCK_JITTER_US)
/* Controller defined back to back transmit MAFS */
#define EVENT_B2B_MAFS_US (CONFIG_BT_CTLR_ADV_PDU_BACK2BACK_AFS)
/* Minimum Subevent Space timings */ /* Minimum Subevent Space timings */
#define EVENT_MSS_US 150 #define EVENT_MSS_US 150
/* Standard allows 2 us timing uncertainty inside the event */ /* Standard allows 2 us timing uncertainty inside the event */

View file

@ -16,6 +16,7 @@ CONFIG_BT_CTLR_ADVANCED_FEATURES=y
CONFIG_BT_CTLR_PHY_2M=y CONFIG_BT_CTLR_PHY_2M=y
CONFIG_BT_CTLR_PHY_2M_NRF=y CONFIG_BT_CTLR_PHY_2M_NRF=y
CONFIG_BT_CTLR_PHY_CODED=y CONFIG_BT_CTLR_PHY_CODED=y
CONFIG_BT_CTLR_ADV_PDU_BACK2BACK=y
CONFIG_BT_CTLR_LLL_PRIO=0 CONFIG_BT_CTLR_LLL_PRIO=0
CONFIG_BT_CTLR_ULL_HIGH_PRIO=1 CONFIG_BT_CTLR_ULL_HIGH_PRIO=1
CONFIG_BT_CTLR_XTAL_ADVANCED=n CONFIG_BT_CTLR_XTAL_ADVANCED=n