@@ -51,6 +51,9 @@ static void isr_done(void *param);
5151
5252#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK )
5353static void isr_tx (void * param );
54+ static int aux_ptr_get (struct pdu_adv * pdu , struct pdu_adv_aux_ptr * * aux_ptr );
55+ static void chain_pdu_aux_ptr_chan_idx_set (struct lll_adv_sync * lll );
56+ static void aux_ptr_chan_idx_set (struct lll_adv_sync * lll , struct pdu_adv * pdu );
5457static void switch_radio_complete_and_b2b_tx (const struct lll_adv_sync * lll , uint8_t phy_s );
5558#endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK */
5659
@@ -181,22 +184,38 @@ static int prepare_cb(struct lll_prepare_param *p)
181184 cte_len_us = 0U ;
182185#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX) */
183186
184- radio_pkt_tx_set (pdu );
185-
186187#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK )
187188 if (pdu -> adv_ext_ind .ext_hdr_len && pdu -> adv_ext_ind .ext_hdr .aux_ptr ) {
189+ /* Set the last used auxiliary PDU for transmission */
188190 lll -> last_pdu = pdu ;
189191
192+ /* Populate chan idx for AUX_ADV_IND PDU */
193+ aux_ptr_chan_idx_set (lll , pdu );
194+
190195 radio_isr_set (isr_tx , lll );
191196 radio_tmr_tifs_set (EVENT_SYNC_B2B_MAFS_US );
192197 switch_radio_complete_and_b2b_tx (lll , phy_s );
193- } else
194- #endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK */
198+ } else {
199+ /* No chain PDU */
200+ lll -> last_pdu = NULL ;
201+
202+ #else /* !CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK */
195203 {
204+ #endif /* !CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK */
205+
196206 radio_isr_set (isr_done , lll );
197207 radio_switch_complete_and_disable ();
198208 }
199209
210+ #if defined(CONFIG_BT_CTLR_ADV_ISO ) && defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO )
211+ if (lll -> iso ) {
212+ ull_adv_iso_lll_biginfo_fill (pdu , lll );
213+ }
214+ #endif /* CONFIG_BT_CTLR_ADV_ISO && CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
215+
216+ /* Set the Radio Tx Packet */
217+ radio_pkt_tx_set (pdu );
218+
200219 ticks_at_event = p -> ticks_at_expire ;
201220 ull = HDR_LLL2ULL (lll );
202221 ticks_at_event += lll_event_offset_get (ull );
@@ -253,11 +272,10 @@ static int prepare_cb(struct lll_prepare_param *p)
253272 }
254273#endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */
255274
256- #if defined(CONFIG_BT_CTLR_ADV_ISO ) && defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO )
257- if (lll -> iso ) {
258- ull_adv_iso_lll_biginfo_fill (pdu , lll );
259- }
260- #endif /* CONFIG_BT_CTLR_ADV_ISO && CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
275+ #if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK )
276+ /* Populate chan idx for AUX_CHAIN_IND PDU */
277+ chain_pdu_aux_ptr_chan_idx_set (lll );
278+ #endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK */
261279
262280 ret = lll_prepare_done (lll );
263281 LL_ASSERT (!ret );
@@ -332,10 +350,12 @@ static void isr_done(void *param)
332350#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK )
333351static void isr_tx (void * param )
334352{
353+ struct pdu_adv_aux_ptr * aux_ptr ;
335354 struct lll_adv_sync * lll_sync ;
336355 struct pdu_adv * pdu ;
337356 struct lll_adv * lll ;
338357 uint32_t cte_len_us ;
358+ int err ;
339359
340360 if (IS_ENABLED (CONFIG_BT_CTLR_PROFILE_ISR )) {
341361 lll_prof_latency_capture ();
@@ -344,14 +364,22 @@ static void isr_tx(void *param)
344364 /* Clear radio tx status and events */
345365 lll_isr_tx_status_reset ();
346366
367+ /* Get reference to sync and primary advertising LLL contexts */
347368 lll_sync = param ;
348369 lll = lll_sync -> adv ;
349370
350- /* FIXME: Use implementation defined channel index */
351- lll_chan_set (0 );
371+ /* Get reference to aux pointer structure */
372+ err = aux_ptr_get (lll_sync -> last_pdu , & aux_ptr );
373+ LL_ASSERT (!err && aux_ptr );
352374
375+ /* Use channel idx that was in aux_ptr */
376+ lll_chan_set (aux_ptr -> chan_idx );
377+
378+ /* Get reference to the auxiliary chain PDU */
353379 pdu = lll_adv_pdu_linked_next_get (lll_sync -> last_pdu );
354380 LL_ASSERT (pdu );
381+
382+ /* Set the last used auxiliary PDU for transmission */
355383 lll_sync -> last_pdu = pdu ;
356384
357385#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX )
@@ -403,11 +431,97 @@ static void isr_tx(void *param)
403431 HAL_RADIO_GPIO_PA_OFFSET );
404432#endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
405433
434+ /* Populate chan idx for AUX_CHAIN_IND PDU */
435+ chain_pdu_aux_ptr_chan_idx_set (lll_sync );
436+
406437 if (IS_ENABLED (CONFIG_BT_CTLR_PROFILE_ISR )) {
407438 lll_prof_send ();
408439 }
409440}
410441
442+ static int aux_ptr_get (struct pdu_adv * pdu , struct pdu_adv_aux_ptr * * aux_ptr )
443+ {
444+ struct pdu_adv_com_ext_adv * com_hdr ;
445+ struct pdu_adv_ext_hdr * hdr ;
446+ uint8_t * dptr ;
447+
448+ /* Get reference to common extended header */
449+ com_hdr = (void * )& pdu -> adv_ext_ind ;
450+ if (com_hdr -> ext_hdr_len == 0U ) {
451+ return - EINVAL ;
452+ }
453+
454+ /* Get reference to extended header flags and header fields */
455+ hdr = (void * )com_hdr -> ext_hdr_adv_data ;
456+ dptr = hdr -> data ;
457+
458+ /* No traverse through of AdvA and TargetA.
459+ * These are RFU for periodic advertising, is not set by local device.
460+ */
461+
462+ /* traverse through CTEInfo flag, if present */
463+ #if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX )
464+ if (hdr -> cte_info ) {
465+ dptr += sizeof (struct pdu_cte_info );
466+ }
467+ #endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
468+
469+ /* traverse through adi, if present */
470+ if (hdr -> adi ) {
471+ dptr += sizeof (struct pdu_adv_adi );
472+ }
473+
474+ /* check for aux_ptr flag */
475+ if (hdr -> aux_ptr ) {
476+ /* Return reference to aux pointer structure */
477+ * aux_ptr = (void * )dptr ;
478+ } else {
479+ * aux_ptr = NULL ;
480+ }
481+
482+ return 0 ;
483+ }
484+
485+ static void chain_pdu_aux_ptr_chan_idx_set (struct lll_adv_sync * lll )
486+ {
487+ struct pdu_adv * chain_pdu ;
488+
489+ /* No chain PDU */
490+ if (!lll -> last_pdu ) {
491+ return ;
492+ }
493+
494+ /* Get reference to the auxiliary chain PDU */
495+ chain_pdu = lll_adv_pdu_linked_next_get (lll -> last_pdu );
496+
497+ /* Check if there is further chain PDU */
498+ if (chain_pdu && chain_pdu -> adv_ext_ind .ext_hdr_len &&
499+ chain_pdu -> adv_ext_ind .ext_hdr .aux_ptr ) {
500+ aux_ptr_chan_idx_set (lll , chain_pdu );
501+ }
502+ }
503+
504+ static void aux_ptr_chan_idx_set (struct lll_adv_sync * lll , struct pdu_adv * pdu )
505+ {
506+ struct pdu_adv_aux_ptr * aux_ptr ;
507+ uint8_t chan_idx ;
508+ int err ;
509+
510+ /* Get reference to aux pointer structure */
511+ err = aux_ptr_get (pdu , & aux_ptr );
512+ LL_ASSERT (!err && aux_ptr );
513+
514+ /* Calculate a new channel index */
515+ chan_idx = lll_chan_sel_2 (lll -> data_chan_counter , lll -> data_chan_id ,
516+ lll -> chm [lll -> chm_first ].data_chan_map ,
517+ lll -> chm [lll -> chm_first ].data_chan_count );
518+
519+ /* Increment counter, for next channel index calculation */
520+ lll -> data_chan_counter ++ ;
521+
522+ /* Set the channel index for the auxiliary chain PDU */
523+ aux_ptr -> chan_idx = chan_idx ;
524+ }
411525static void switch_radio_complete_and_b2b_tx (const struct lll_adv_sync * lll ,
412526 uint8_t phy_s )
413527{
0 commit comments