Skip to content

Commit 2d71b2d

Browse files
ppryga-nordiccfriedt
authored andcommitted
Bluetooth: controller: LLL: Add CTE confing for per. adv. chain TX
Add configuration of CTE for periodic advertising chain transmission. The commit provides configuration of radio in prepare stage and in handle of Tx ISR. CTE is configured only for PDUs that have cte_info field in extended advertising header. During prepare of periodic advertising event there are updated aux_ptr fields in extended advertising header in other PDUs from a periodic advertising chain. aux_ptr offset value also depends on CTE length. CTE configuration is always the same for every PDU in periodic advertising chain. CTE may be added to requested number of PDUs in periodic advertising chain. Although it is possible that there are PDUs that don't have CTE. PDUs that have CTE are alsways at the beginning of a periodic advertising chain. Signed-off-by: Piotr Pryga <[email protected]>
1 parent 8a5a88c commit 2d71b2d

File tree

3 files changed

+172
-106
lines changed

3 files changed

+172
-106
lines changed

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_sync.c

Lines changed: 75 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,23 @@
4242
#include "hal/debug.h"
4343

4444
#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK)
45-
#define ADV_SYNC_PDU_B2B_AFS (CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK_AFS)
45+
#define ADV_SYNC_PDU_B2B_AFS (CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK_AFS)
46+
#else
47+
#define ADV_SYNC_PDU_B2B_AFS 0
4648
#endif
4749

4850
static int init_reset(void);
4951
static int prepare_cb(struct lll_prepare_param *p);
5052
static void abort_cb(struct lll_prepare_param *prepare_param, void *param);
5153
static void isr_done(void *param);
54+
static void switch_radio_complete_and_phy_end_disable(const struct lll_adv_sync *lll);
55+
5256
#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK)
5357
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+
static void pdu_b2b_update(struct lll_adv_sync *lll, struct pdu_adv *pdu, uint32_t cte_len_us);
59+
static void pdu_b2b_aux_ptr_update(struct pdu_adv *pdu, uint8_t phy, uint8_t flags,
60+
uint8_t chan_idx, uint32_t offset_us, uint32_t cte_len_us);
61+
static void switch_radio_complete_and_b2b_tx(const struct lll_adv_sync *lll, uint8_t phy_s);
5862
#endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK */
5963

6064
int lll_adv_sync_init(void)
@@ -100,19 +104,16 @@ static int init_reset(void)
100104

101105
static int prepare_cb(struct lll_prepare_param *p)
102106
{
103-
#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
104-
struct lll_df_adv_cfg *df_cfg;
105-
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
106107
struct lll_adv_sync *lll;
107108
uint32_t ticks_at_event;
108109
uint32_t ticks_at_start;
109110
uint16_t event_counter;
110111
uint8_t data_chan_use;
111112
struct pdu_adv *pdu;
112113
struct ull_hdr *ull;
114+
uint32_t cte_len_us;
113115
uint32_t remainder;
114116
uint32_t start_us;
115-
void *extra_data;
116117
uint8_t phy_s;
117118
uint8_t upd;
118119

@@ -157,52 +158,37 @@ static int prepare_cb(struct lll_prepare_param *p)
157158
((uint32_t)lll->crc_init[0])));
158159
lll_chan_set(data_chan_use);
159160

160-
pdu = lll_adv_sync_data_latest_get(lll, &extra_data, &upd);
161+
pdu = lll_adv_sync_data_latest_get(lll, NULL, &upd);
161162
LL_ASSERT(pdu);
162163

164+
#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
165+
lll_df_cte_tx_enable(lll, pdu, &cte_len_us);
166+
#else
167+
cte_len_us = 0U;
168+
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX) */
169+
163170
#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK)
164171
if (upd) {
165172
/* AuxPtr offsets for b2b TX are fixed for given chain so we can
166173
* calculate them here in advance.
167174
*/
168-
pdu_b2b_update(lll, pdu);
175+
pdu_b2b_update(lll, pdu, cte_len_us);
169176
}
170177
#endif
171-
172-
#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
173-
if (extra_data) {
174-
df_cfg = (struct lll_df_adv_cfg *)extra_data;
175-
lll_df_conf_cte_tx_enable(df_cfg->cte_type, df_cfg->cte_length,
176-
df_cfg->ant_sw_len, df_cfg->ant_ids);
177-
lll->cte_started = 1U;
178-
} else {
179-
df_cfg = NULL;
180-
lll->cte_started = 0U;
181-
}
182-
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
183-
184178
radio_pkt_tx_set(pdu);
185179

186180
#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK)
187181
if (pdu->adv_ext_ind.ext_hdr_len && pdu->adv_ext_ind.ext_hdr.aux_ptr) {
188182
lll->last_pdu = pdu;
189183

190184
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) {
185+
radio_tmr_tifs_set(ADV_SYNC_PDU_B2B_AFS + cte_len_us);
186+
switch_radio_complete_and_b2b_tx(lll, phy_s);
187+
} else
195188
#endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK */
196-
} else {
189+
{
197190
radio_isr_set(isr_done, lll);
198-
#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
199-
if (df_cfg) {
200-
radio_switch_complete_and_phy_end_disable();
201-
} else
202-
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
203-
{
204-
radio_switch_complete_and_disable();
205-
}
191+
switch_radio_complete_and_phy_end_disable(lll);
206192
}
207193

208194
ticks_at_event = p->ticks_at_expire;
@@ -294,6 +280,7 @@ static void isr_tx(void *param)
294280
struct lll_adv_sync *lll_sync;
295281
struct pdu_adv *pdu;
296282
struct lll_adv *lll;
283+
uint32_t cte_len_us;
297284

298285
if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
299286
lll_prof_latency_capture();
@@ -312,21 +299,20 @@ static void isr_tx(void *param)
312299
LL_ASSERT(pdu);
313300
lll_sync->last_pdu = pdu;
314301

302+
#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
303+
lll_df_cte_tx_enable(lll_sync, pdu, &cte_len_us);
304+
#else
305+
cte_len_us = 0;
306+
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
307+
315308
/* setup tIFS switching */
316309
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);
310+
radio_tmr_tifs_set(ADV_SYNC_PDU_B2B_AFS + cte_len_us);
318311
radio_isr_set(isr_tx, lll_sync);
319-
radio_switch_complete_and_b2b_tx(lll->phy_s, 0, lll->phy_s, 0);
312+
switch_radio_complete_and_b2b_tx(lll_sync, lll->phy_s);
320313
} 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-
}
314+
radio_isr_set(isr_done, lll);
315+
switch_radio_complete_and_phy_end_disable(lll_sync);
330316
}
331317

332318
radio_pkt_tx_set(pdu);
@@ -352,8 +338,7 @@ static void isr_tx(void *param)
352338
}
353339

354340
radio_gpio_lna_setup();
355-
radio_gpio_pa_lna_enable(radio_tmr_tifs_base_get() +
356-
ADV_SYNC_PDU_B2B_AFS - 4 -
341+
radio_gpio_pa_lna_enable(radio_tmr_tifs_base_get() + ADV_SYNC_PDU_B2B_AFS - 4 + cte_len_us -
357342
radio_tx_chain_delay_get(lll->phy_s, 0) -
358343
CONFIG_BT_CTLR_GPIO_LNA_OFFSET);
359344
#endif /* CONFIG_BT_CTLR_GPIO_LNA_PIN */
@@ -363,23 +348,21 @@ static void isr_tx(void *param)
363348
}
364349
}
365350

366-
static void pdu_b2b_update(struct lll_adv_sync *lll, struct pdu_adv *pdu)
351+
static void pdu_b2b_update(struct lll_adv_sync *lll, struct pdu_adv *pdu, uint32_t cte_len_us)
367352
{
368353
while (pdu) {
369-
pdu_b2b_aux_ptr_update(pdu, lll->adv->phy_s, 0, 0,
370-
ADV_SYNC_PDU_B2B_AFS);
354+
pdu_b2b_aux_ptr_update(pdu, lll->adv->phy_s, 0, 0, ADV_SYNC_PDU_B2B_AFS,
355+
cte_len_us);
371356
pdu = lll_adv_pdu_linked_next_get(pdu);
372357
}
373358
}
374359

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)
360+
static void pdu_b2b_aux_ptr_update(struct pdu_adv *pdu, uint8_t phy, uint8_t flags,
361+
uint8_t chan_idx, uint32_t offset_us, uint32_t cte_len_us)
378362
{
379363
struct pdu_adv_com_ext_adv *com_hdr;
380364
struct pdu_adv_ext_hdr *hdr;
381365
struct pdu_adv_aux_ptr *aux;
382-
uint32_t offs;
383366
uint8_t *dptr;
384367

385368
com_hdr = &pdu->adv_ext_ind;
@@ -402,17 +385,47 @@ static void pdu_b2b_aux_ptr_update(struct pdu_adv *pdu, uint8_t phy,
402385

403386
/* Update AuxPtr */
404387
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);
388+
offset_us += PKT_AC_US(pdu->len, phy);
389+
/* Add CTE length to PDUs that have CTE attached.
390+
* Periodic advertising chain may include PDUs without CTE.
391+
*/
392+
if (hdr->cte_info) {
393+
offset_us += cte_len_us;
394+
}
395+
offset_us = offset_us / OFFS_UNIT_30_US;
396+
if ((offset_us >> 13) != 0) {
397+
aux->offs = offset_us / (OFFS_UNIT_300_US / OFFS_UNIT_30_US);
409398
aux->offs_units = 1U;
410399
} else {
411-
aux->offs = offs;
400+
aux->offs = offset_us;
412401
aux->offs_units = 0U;
413402
}
414403
aux->chan_idx = chan_idx;
415404
aux->ca = 0;
416405
aux->phy = find_lsb_set(phy) - 1;
417406
}
407+
408+
static void switch_radio_complete_and_b2b_tx(const struct lll_adv_sync *lll, uint8_t phy_s)
409+
{
410+
#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
411+
if (lll->cte_started) {
412+
radio_switch_complete_and_phy_end_b2b_tx(phy_s, 0, phy_s, 0);
413+
} else
414+
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
415+
{
416+
radio_switch_complete_and_b2b_tx(phy_s, 0, phy_s, 0);
417+
}
418+
}
418419
#endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK */
420+
421+
static void switch_radio_complete_and_phy_end_disable(const struct lll_adv_sync *lll)
422+
{
423+
#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
424+
if (lll->cte_started) {
425+
radio_switch_complete_and_phy_end_disable();
426+
} else
427+
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
428+
{
429+
radio_switch_complete_and_disable();
430+
}
431+
}

0 commit comments

Comments
 (0)