3333#include "lll_internal.h"
3434#include "lll_adv_internal.h"
3535#include "lll_tim_internal.h"
36+ #include "lll_prof_internal.h"
3637#include "lll_df_internal.h"
3738
3839#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
3940#define LOG_MODULE_NAME bt_ctlr_lll_adv_sync
4041#include "common/log.h"
4142#include "hal/debug.h"
4243
44+ #if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK )
45+ #define ADV_SYNC_PDU_B2B_AFS (CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK_AFS)
46+ #endif
47+
4348static int init_reset (void );
4449static int prepare_cb (struct lll_prepare_param * p );
4550static void abort_cb (struct lll_prepare_param * prepare_param , void * param );
4651static void isr_done (void * param );
52+ #if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK )
53+ static void isr_tx (void * param );
54+ static void pdu_b2b_update (struct lll_adv_sync * lll , struct pdu_adv * pdu );
55+ static void pdu_b2b_aux_ptr_update (struct pdu_adv * pdu , uint8_t phy ,
56+ uint8_t flags , uint8_t chan_idx ,
57+ uint32_t tifs );
58+ #endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK */
4759
4860int lll_adv_sync_init (void )
4961{
@@ -148,6 +160,15 @@ static int prepare_cb(struct lll_prepare_param *p)
148160 pdu = lll_adv_sync_data_latest_get (lll , & extra_data , & upd );
149161 LL_ASSERT (pdu );
150162
163+ #if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK )
164+ if (upd ) {
165+ /* AuxPtr offsets for b2b TX are fixed for given chain so we can
166+ * calculate them here in advance.
167+ */
168+ pdu_b2b_update (lll , pdu );
169+ }
170+ #endif
171+
151172#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX )
152173 if (extra_data ) {
153174 df_cfg = (struct lll_df_adv_cfg * )extra_data ;
@@ -162,16 +183,26 @@ static int prepare_cb(struct lll_prepare_param *p)
162183
163184 radio_pkt_tx_set (pdu );
164185
165- /* TODO: chaining */
166- radio_isr_set (isr_done , lll );
186+ #if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK )
187+ if (pdu -> adv_ext_ind .ext_hdr_len && pdu -> adv_ext_ind .ext_hdr .aux_ptr ) {
188+ lll -> last_pdu = pdu ;
167189
190+ radio_isr_set (isr_tx , lll );
191+ radio_tmr_tifs_set (ADV_SYNC_PDU_B2B_AFS );
192+ radio_switch_complete_and_b2b_tx (phy_s , 0 , phy_s , 0 );
193+ #else
194+ if (0 ) {
195+ #endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK */
196+ } else {
197+ radio_isr_set (isr_done , lll );
168198#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX )
169- if (df_cfg ) {
170- radio_switch_complete_and_phy_end_disable ();
171- } else
199+ if (df_cfg ) {
200+ radio_switch_complete_and_phy_end_disable ();
201+ } else
172202#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
173- {
174- radio_switch_complete_and_disable ();
203+ {
204+ radio_switch_complete_and_disable ();
205+ }
175206 }
176207
177208 ticks_at_event = p -> ticks_at_expire ;
@@ -256,3 +287,132 @@ static void isr_done(void *param)
256287#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
257288 lll_isr_done (lll );
258289}
290+
291+ #if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK )
292+ static void isr_tx (void * param )
293+ {
294+ struct lll_adv_sync * lll_sync ;
295+ struct pdu_adv * pdu ;
296+ struct lll_adv * lll ;
297+
298+ if (IS_ENABLED (CONFIG_BT_CTLR_PROFILE_ISR )) {
299+ lll_prof_latency_capture ();
300+ }
301+
302+ /* Clear radio tx status and events */
303+ lll_isr_tx_status_reset ();
304+
305+ lll_sync = param ;
306+ lll = lll_sync -> adv ;
307+
308+ /* TODO: do not hardcode to single value */
309+ lll_chan_set (0 );
310+
311+ pdu = lll_adv_pdu_linked_next_get (lll_sync -> last_pdu );
312+ LL_ASSERT (pdu );
313+ lll_sync -> last_pdu = pdu ;
314+
315+ /* setup tIFS switching */
316+ if (pdu -> adv_ext_ind .ext_hdr_len && pdu -> adv_ext_ind .ext_hdr .aux_ptr ) {
317+ radio_tmr_tifs_set (ADV_SYNC_PDU_B2B_AFS );
318+ radio_isr_set (isr_tx , lll_sync );
319+ radio_switch_complete_and_b2b_tx (lll -> phy_s , 0 , lll -> phy_s , 0 );
320+ } else {
321+ radio_isr_set (lll_isr_done , lll );
322+ #if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX )
323+ if (lll_sync -> cte_started ) {
324+ radio_switch_complete_and_phy_end_disable ();
325+ } else
326+ #endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
327+ {
328+ radio_switch_complete_and_disable ();
329+ }
330+ }
331+
332+ radio_pkt_tx_set (pdu );
333+
334+ /* assert if radio packet ptr is not set and radio started rx */
335+ LL_ASSERT (!radio_is_ready ());
336+
337+ if (IS_ENABLED (CONFIG_BT_CTLR_PROFILE_ISR )) {
338+ lll_prof_cputime_capture ();
339+ }
340+
341+ /* capture end of AUX_SYNC_IND/AUX_CHAIN_IND PDU, used for calculating
342+ * next PDU timestamp.
343+ */
344+ radio_tmr_end_capture ();
345+
346+ #if defined(CONFIG_BT_CTLR_GPIO_LNA_PIN )
347+ if (IS_ENABLED (CONFIG_BT_CTLR_PROFILE_ISR )) {
348+ /* PA/LNA enable is overwriting packet end used in ISR
349+ * profiling, hence back it up for later use.
350+ */
351+ lll_prof_radio_end_backup ();
352+ }
353+
354+ radio_gpio_lna_setup ();
355+ radio_gpio_pa_lna_enable (radio_tmr_tifs_base_get () +
356+ ADV_SYNC_PDU_B2B_AFS - 4 -
357+ radio_tx_chain_delay_get (lll -> phy_s , 0 ) -
358+ CONFIG_BT_CTLR_GPIO_LNA_OFFSET );
359+ #endif /* CONFIG_BT_CTLR_GPIO_LNA_PIN */
360+
361+ if (IS_ENABLED (CONFIG_BT_CTLR_PROFILE_ISR )) {
362+ lll_prof_send ();
363+ }
364+ }
365+
366+ static void pdu_b2b_update (struct lll_adv_sync * lll , struct pdu_adv * pdu )
367+ {
368+ while (pdu ) {
369+ pdu_b2b_aux_ptr_update (pdu , lll -> adv -> phy_s , 0 , 0 ,
370+ ADV_SYNC_PDU_B2B_AFS );
371+ pdu = lll_adv_pdu_linked_next_get (pdu );
372+ }
373+ }
374+
375+ static void pdu_b2b_aux_ptr_update (struct pdu_adv * pdu , uint8_t phy ,
376+ uint8_t flags , uint8_t chan_idx ,
377+ uint32_t tifs )
378+ {
379+ struct pdu_adv_com_ext_adv * com_hdr ;
380+ struct pdu_adv_ext_hdr * hdr ;
381+ struct pdu_adv_aux_ptr * aux ;
382+ uint32_t offs ;
383+ uint8_t * dptr ;
384+
385+ com_hdr = & pdu -> adv_ext_ind ;
386+ hdr = & com_hdr -> ext_hdr ;
387+ /* Skip flags */
388+ dptr = hdr -> data ;
389+
390+ if (!com_hdr -> ext_hdr_len || !hdr -> aux_ptr ) {
391+ return ;
392+ }
393+
394+ LL_ASSERT (!hdr -> adv_addr );
395+ LL_ASSERT (!hdr -> tgt_addr );
396+
397+ if (hdr -> cte_info ) {
398+ dptr ++ ;
399+ }
400+
401+ LL_ASSERT (!hdr -> adi );
402+
403+ /* Update AuxPtr */
404+ aux = (void * )dptr ;
405+ offs = PKT_AC_US (pdu -> len , phy ) + tifs ;
406+ offs = offs / OFFS_UNIT_30_US ;
407+ if ((offs >> 13 ) != 0 ) {
408+ aux -> offs = offs / (OFFS_UNIT_300_US / OFFS_UNIT_30_US );
409+ aux -> offs_units = 1U ;
410+ } else {
411+ aux -> offs = offs ;
412+ aux -> offs_units = 0U ;
413+ }
414+ aux -> chan_idx = chan_idx ;
415+ aux -> ca = 0 ;
416+ aux -> phy = find_lsb_set (phy ) - 1 ;
417+ }
418+ #endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK */
0 commit comments