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_IFS (EVENT_MAFS_US)
46+ #endif
47+
4348static int init_reset (void );
4449static int prepare_cb (struct lll_prepare_param * p );
4550static void isr_done (void * param );
51+ #if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK )
52+ static void isr_tx (void * param );
53+ static void pdu_b2b_update (struct lll_adv_sync * lll , struct pdu_adv * pdu );
54+ static void pdu_b2b_aux_ptr_update (struct pdu_adv * pdu , uint8_t phy ,
55+ uint8_t flags , uint8_t chan_idx ,
56+ uint32_t tifs );
57+ #endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK */
4658
4759int lll_adv_sync_init (void )
4860{
@@ -160,6 +172,15 @@ static int prepare_cb(struct lll_prepare_param *p)
160172 pdu = lll_adv_sync_data_latest_get (lll , & extra_data , & upd );
161173 LL_ASSERT (pdu );
162174
175+ #if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK )
176+ if (upd ) {
177+ /* AuxPtr offsets for b2b TX are fixed for given chain so we can
178+ * calculate them here in advance.
179+ */
180+ pdu_b2b_update (lll , pdu );
181+ }
182+ #endif
183+
163184#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX )
164185 if (extra_data ) {
165186 df_cfg = (struct lll_df_adv_cfg * )extra_data ;
@@ -174,17 +195,29 @@ static int prepare_cb(struct lll_prepare_param *p)
174195
175196 radio_pkt_tx_set (pdu );
176197
177- /* TODO: chaining */
178- radio_isr_set ( lll_isr_done , lll );
179- radio_isr_set ( isr_done , lll ) ;
198+ #if defined( CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK )
199+ if ( pdu -> adv_ext_ind . ext_hdr_len && pdu -> adv_ext_ind . ext_hdr . aux_ptr ) {
200+ lll -> last_pdu = pdu ;
180201
202+ radio_isr_set (isr_tx , lll );
203+ radio_tmr_tifs_set (ADV_SYNC_PDU_B2B_IFS );
204+ radio_switch_complete_and_b2b_tx (phy_s , 0 , phy_s , 0 );
205+ #else
206+ if (0 ) {
207+ #endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK */
208+ } else {
209+ /* There should be no AuxPtr without piggyback enabled */
210+ LL_ASSERT (!pdu -> adv_ext_ind .ext_hdr .aux_ptr );
211+
212+ radio_isr_set (isr_done , lll );
181213#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX )
182- if (df_cfg ) {
183- radio_switch_complete_and_phy_end_disable ();
184- } else
214+ if (df_cfg ) {
215+ radio_switch_complete_and_phy_end_disable ();
216+ } else
185217#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
186- {
187- radio_switch_complete_and_disable ();
218+ {
219+ radio_switch_complete_and_disable ();
220+ }
188221 }
189222
190223 ticks_at_event = p -> ticks_at_expire ;
@@ -240,3 +273,139 @@ static void isr_done(void *param)
240273#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
241274 lll_isr_done (lll );
242275}
276+
277+ #if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK )
278+ static void isr_tx (void * param )
279+ {
280+ struct lll_adv_sync * lll_sync ;
281+ struct pdu_adv * pdu ;
282+ struct lll_adv * lll ;
283+ uint32_t hcto ;
284+
285+ if (IS_ENABLED (CONFIG_BT_CTLR_PROFILE_ISR )) {
286+ lll_prof_latency_capture ();
287+ }
288+
289+ /* Clear radio tx status and events */
290+ lll_isr_tx_status_reset ();
291+
292+ lll_sync = param ;
293+ lll = lll_sync -> adv ;
294+
295+ /* TODO: do not hardcode to single value */
296+ lll_chan_set (0 );
297+
298+ pdu = lll_adv_pdu_linked_next_get (lll_sync -> last_pdu );
299+ LL_ASSERT (pdu );
300+ lll_sync -> last_pdu = pdu ;
301+
302+ /* setup tIFS switching */
303+ if (pdu -> adv_ext_ind .ext_hdr_len && pdu -> adv_ext_ind .ext_hdr .aux_ptr ) {
304+ radio_tmr_tifs_set (ADV_SYNC_PDU_B2B_IFS );
305+ radio_isr_set (isr_tx , lll_sync );
306+ radio_switch_complete_and_b2b_tx (lll -> phy_s , 0 , lll -> phy_s , 0 );
307+ } else {
308+ radio_isr_set (lll_isr_done , lll );
309+ #if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX )
310+ if (df_cfg ) {
311+ radio_switch_complete_and_phy_end_disable ();
312+ } else
313+ #endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
314+ {
315+ radio_switch_complete_and_disable ();
316+ }
317+ }
318+
319+ radio_pkt_tx_set (pdu );
320+
321+ /* assert if radio packet ptr is not set and radio started rx */
322+ LL_ASSERT (!radio_is_ready ());
323+
324+ if (IS_ENABLED (CONFIG_BT_CTLR_PROFILE_ISR )) {
325+ lll_prof_cputime_capture ();
326+ }
327+
328+ /* +/- 2us active clock jitter, +1 us hcto compensation */
329+ hcto = radio_tmr_tifs_base_get () + ADV_SYNC_PDU_B2B_IFS + 4 + 1 ;
330+ hcto += radio_tx_chain_delay_get (lll -> phy_s , 1 );
331+ hcto += addr_us_get (lll -> phy_s );
332+ hcto -= radio_tx_chain_delay_get (lll -> phy_s , 0 );
333+ radio_tmr_hcto_configure (hcto );
334+
335+ /* capture end of AUX_SYNC_IND/AUX_CHAIN_IND PDU, used for calculating
336+ * next PDU timestamp.
337+ */
338+ radio_tmr_end_capture ();
339+
340+ #if defined(CONFIG_BT_CTLR_GPIO_LNA_PIN )
341+ if (IS_ENABLED (CONFIG_BT_CTLR_PROFILE_ISR )) {
342+ /* PA/LNA enable is overwriting packet end used in ISR
343+ * profiling, hence back it up for later use.
344+ */
345+ lll_prof_radio_end_backup ();
346+ }
347+
348+ radio_gpio_lna_setup ();
349+ radio_gpio_pa_lna_enable (radio_tmr_tifs_base_get () + ADV_SYNC_PDU_B2B_IFS - 4 -
350+ radio_tx_chain_delay_get (lll -> phy_s , 0 ) -
351+ CONFIG_BT_CTLR_GPIO_LNA_OFFSET );
352+ #endif /* CONFIG_BT_CTLR_GPIO_LNA_PIN */
353+
354+ if (IS_ENABLED (CONFIG_BT_CTLR_PROFILE_ISR )) {
355+ lll_prof_send ();
356+ }
357+ }
358+
359+ static void pdu_b2b_update (struct lll_adv_sync * lll , struct pdu_adv * pdu )
360+ {
361+ while (pdu ) {
362+ pdu_b2b_aux_ptr_update (pdu , lll -> adv -> phy_s , 0 , 0 ,
363+ ADV_SYNC_PDU_B2B_IFS );
364+ pdu = lll_adv_pdu_linked_next_get (pdu );
365+ }
366+ }
367+
368+ static void pdu_b2b_aux_ptr_update (struct pdu_adv * pdu , uint8_t phy ,
369+ uint8_t flags , uint8_t chan_idx ,
370+ uint32_t tifs )
371+ {
372+ struct pdu_adv_com_ext_adv * com_hdr ;
373+ struct pdu_adv_ext_hdr * hdr ;
374+ struct pdu_adv_aux_ptr * aux ;
375+ uint32_t offs ;
376+ uint8_t * dptr ;
377+
378+ com_hdr = & pdu -> adv_ext_ind ;
379+ hdr = & com_hdr -> ext_hdr ;
380+ /* Skip flags */
381+ dptr = hdr -> data ;
382+
383+ if (!hdr -> aux_ptr ) {
384+ return pdu ;
385+ }
386+
387+ LL_ASSERT (!hdr -> adv_addr );
388+ LL_ASSERT (!hdr -> tgt_addr );
389+
390+ if (hdr -> cte_info ) {
391+ dptr ++ ;
392+ }
393+
394+ LL_ASSERT (!hdr -> adi );
395+
396+ /* Update AuxPtr */
397+ aux = (void * )dptr ;
398+ offs = PKT_AC_US (pdu -> len , phy ) + tifs ;
399+ offs = offs / OFFS_UNIT_30_US ;
400+ if (!!(offs >> 13 )) {
401+ aux -> offs = offs / (OFFS_UNIT_300_US / OFFS_UNIT_30_US );
402+ aux -> offs_units = 1U ;
403+ } else {
404+ aux -> offs = offs ;
405+ aux -> offs_units = 0U ;
406+ }
407+ aux -> chan_idx = chan_idx ;
408+ aux -> ca = 0 ;
409+ aux -> phy = find_lsb_set (phy ) - 1 ;
410+ }
411+ #endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK */
0 commit comments