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,140 @@ 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+ 	uint32_t  hcto ;
298+ 
299+ 	if  (IS_ENABLED (CONFIG_BT_CTLR_PROFILE_ISR )) {
300+ 		lll_prof_latency_capture ();
301+ 	}
302+ 
303+ 	/* Clear radio tx status and events */ 
304+ 	lll_isr_tx_status_reset ();
305+ 
306+ 	lll_sync  =  param ;
307+ 	lll  =  lll_sync -> adv ;
308+ 
309+ 	/* TODO: do not hardcode to single value */ 
310+ 	lll_chan_set (0 );
311+ 
312+ 	pdu  =  lll_adv_pdu_linked_next_get (lll_sync -> last_pdu );
313+ 	LL_ASSERT (pdu );
314+ 	lll_sync -> last_pdu  =  pdu ;
315+ 
316+ 	/* setup tIFS switching */ 
317+ 	if  (pdu -> adv_ext_ind .ext_hdr_len  &&  pdu -> adv_ext_ind .ext_hdr .aux_ptr ) {
318+ 		radio_tmr_tifs_set (ADV_SYNC_PDU_B2B_AFS );
319+ 		radio_isr_set (isr_tx , lll_sync );
320+ 		radio_switch_complete_and_b2b_tx (lll -> phy_s , 0 , lll -> phy_s , 0 );
321+ 	} else  {
322+ 		radio_isr_set (lll_isr_done , lll );
323+ #if  defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX )
324+ 		if  (lll_sync -> cte_started ) {
325+ 			radio_switch_complete_and_phy_end_disable ();
326+ 		} else 
327+ #endif  /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */ 
328+ 		{
329+ 			radio_switch_complete_and_disable ();
330+ 		}
331+ 	}
332+ 
333+ 	radio_pkt_tx_set (pdu );
334+ 
335+ 	/* assert if radio packet ptr is not set and radio started rx */ 
336+ 	LL_ASSERT (!radio_is_ready ());
337+ 
338+ 	if  (IS_ENABLED (CONFIG_BT_CTLR_PROFILE_ISR )) {
339+ 		lll_prof_cputime_capture ();
340+ 	}
341+ 
342+ 	/* +/- 2us active clock jitter, +1 us hcto compensation */ 
343+ 	hcto  =  radio_tmr_tifs_base_get () +  ADV_SYNC_PDU_B2B_AFS  +  4  +  1 ;
344+ 	hcto  +=  radio_tx_chain_delay_get (lll -> phy_s , 1 );
345+ 	hcto  +=  addr_us_get (lll -> phy_s );
346+ 	hcto  -=  radio_tx_chain_delay_get (lll -> phy_s , 0 );
347+ 	radio_tmr_hcto_configure (hcto );
348+ 
349+ 	/* capture end of AUX_SYNC_IND/AUX_CHAIN_IND PDU, used for calculating 
350+ 	 * next PDU timestamp. 
351+ 	 */ 
352+ 	radio_tmr_end_capture ();
353+ 
354+ #if  defined(CONFIG_BT_CTLR_GPIO_LNA_PIN )
355+ 	if  (IS_ENABLED (CONFIG_BT_CTLR_PROFILE_ISR )) {
356+ 		/* PA/LNA enable is overwriting packet end used in ISR 
357+ 		 * profiling, hence back it up for later use. 
358+ 		 */ 
359+ 		lll_prof_radio_end_backup ();
360+ 	}
361+ 
362+ 	radio_gpio_lna_setup ();
363+ 	radio_gpio_pa_lna_enable (radio_tmr_tifs_base_get () + 
364+ 				 ADV_SYNC_PDU_B2B_AFS  -  4  - 
365+ 				 radio_tx_chain_delay_get (lll -> phy_s , 0 ) - 
366+ 				 CONFIG_BT_CTLR_GPIO_LNA_OFFSET );
367+ #endif  /* CONFIG_BT_CTLR_GPIO_LNA_PIN */ 
368+ 
369+ 	if  (IS_ENABLED (CONFIG_BT_CTLR_PROFILE_ISR )) {
370+ 		lll_prof_send ();
371+ 	}
372+ }
373+ 
374+ static  void  pdu_b2b_update (struct  lll_adv_sync  * lll , struct  pdu_adv  * pdu )
375+ {
376+ 	while  (pdu ) {
377+ 		pdu_b2b_aux_ptr_update (pdu , lll -> adv -> phy_s , 0 , 0 ,
378+ 				       ADV_SYNC_PDU_B2B_AFS );
379+ 		pdu  =  lll_adv_pdu_linked_next_get (pdu );
380+ 	}
381+ }
382+ 
383+ static  void  pdu_b2b_aux_ptr_update (struct  pdu_adv  * pdu , uint8_t  phy ,
384+ 				   uint8_t  flags , uint8_t  chan_idx ,
385+ 				   uint32_t  tifs )
386+ {
387+ 	struct  pdu_adv_com_ext_adv  * com_hdr ;
388+ 	struct  pdu_adv_ext_hdr  * hdr ;
389+ 	struct  pdu_adv_aux_ptr  * aux ;
390+ 	uint32_t  offs ;
391+ 	uint8_t  * dptr ;
392+ 
393+ 	com_hdr  =  & pdu -> adv_ext_ind ;
394+ 	hdr  =  & com_hdr -> ext_hdr ;
395+ 	/* Skip flags */ 
396+ 	dptr  =  hdr -> data ;
397+ 
398+ 	if  (!com_hdr -> ext_hdr_len  ||  !hdr -> aux_ptr ) {
399+ 		return ;
400+ 	}
401+ 
402+ 	LL_ASSERT (!hdr -> adv_addr );
403+ 	LL_ASSERT (!hdr -> tgt_addr );
404+ 
405+ 	if  (hdr -> cte_info ) {
406+ 		dptr ++ ;
407+ 	}
408+ 
409+ 	LL_ASSERT (!hdr -> adi );
410+ 
411+ 	/* Update AuxPtr */ 
412+ 	aux  =  (void  * )dptr ;
413+ 	offs  =  PKT_AC_US (pdu -> len , phy ) +  tifs ;
414+ 	offs  =  offs  / OFFS_UNIT_30_US ;
415+ 	if  ((offs  >> 13 ) !=  0 ) {
416+ 		aux -> offs  =  offs  / (OFFS_UNIT_300_US  / OFFS_UNIT_30_US );
417+ 		aux -> offs_units  =  1U ;
418+ 	} else  {
419+ 		aux -> offs  =  offs ;
420+ 		aux -> offs_units  =  0U ;
421+ 	}
422+ 	aux -> chan_idx  =  chan_idx ;
423+ 	aux -> ca  =  0 ;
424+ 	aux -> phy  =  find_lsb_set (phy ) -  1 ;
425+ }
426+ #endif  /* CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK */ 
0 commit comments