Skip to content

Commit cf47d53

Browse files
ppryga-nordicnashif
authored andcommitted
Bluetooth: controller: LLL: enable TX of CTE with per. adv. PDU
Enable transmission of CTE with periodic advertising PDU. Signed-off-by: Piotr Pryga <[email protected]>
1 parent 515f953 commit cf47d53

File tree

5 files changed

+245
-98
lines changed

5 files changed

+245
-98
lines changed

subsys/bluetooth/controller/Kconfig.df

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ config BT_CTLR_DF_ADV_CTE_TX
110110

111111
config BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN
112112
int "Maximum length of antenna switch pattern"
113-
range 3 40 if SOC_COMPATIBLE_NRF
113+
range 3 39 if SOC_COMPATIBLE_NRF
114114
range 2 75 if !SOC_COMPATIBLE_NRF
115115
default 12
116116
help

subsys/bluetooth/controller/ll_sw/lll_df_internal.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,14 @@ struct lll_df_adv_cfg {
2525
/* @brief Min supported length of antenna switching pattern */
2626
#define LLL_DF_MIN_ANT_PATTERN_LEN 3
2727

28+
/* @brief Macro to convert length of CTE to [us] */
29+
#define CTE_LEN_US(n) ((n) * 8U)
30+
2831
/* Provides number of available antennae for Direction Finding */
2932
uint8_t lll_df_ant_num_get(void);
33+
34+
/* Enables CTE transmission according to provided configuration */
35+
void lll_df_conf_cte_tx_enable(uint8_t type, uint8_t length,
36+
uint8_t ant_num, uint8_t *ant_ids);
37+
/* Disables CTE transmission */
38+
void lll_df_conf_cte_tx_disable(void);

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

Lines changed: 141 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,24 @@
3939
#include "lll_tim_internal.h"
4040
#include "lll_adv_internal.h"
4141
#include "lll_prof_internal.h"
42+
#if IS_ENABLED(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
4243
#include "lll_df_internal.h"
44+
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
4345

4446
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
4547
#define LOG_MODULE_NAME bt_ctlr_lll_adv
4648
#include "common/log.h"
4749
#include "hal/debug.h"
4850

4951
static int init_reset(void);
52+
53+
static struct pdu_adv *adv_pdu_allocate(struct lll_adv_pdu *pdu, uint8_t last);
54+
#if IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY)
55+
static inline void adv_extra_data_release(struct lll_adv_pdu *pdu, int idx);
56+
static void *adv_extra_data_allocate(struct lll_adv_pdu *pdu, uint8_t last);
57+
static int adv_extra_data_free(struct lll_adv_pdu *pdu, uint8_t last);
58+
#endif /* CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY */
59+
5060
static int prepare_cb(struct lll_prepare_param *p);
5161
static int is_abort_cb(void *next, int prio, void *curr,
5262
lll_prepare_cb_t *resume_cb, int *resume_prio);
@@ -243,46 +253,6 @@ int lll_adv_data_release(struct lll_adv_pdu *pdu)
243253
return 0;
244254
}
245255

246-
static inline struct pdu_adv *adv_pdu_allocate(struct lll_adv_pdu *pdu,
247-
uint8_t last)
248-
{
249-
void *p;
250-
int err;
251-
252-
p = (void *)pdu->pdu[last];
253-
if (p) {
254-
return p;
255-
}
256-
257-
p = MFIFO_DEQUEUE_PEEK(pdu_free);
258-
if (p) {
259-
err = k_sem_take(&sem_pdu_free, K_NO_WAIT);
260-
LL_ASSERT(!err);
261-
262-
MFIFO_DEQUEUE(pdu_free);
263-
pdu->pdu[last] = (void *)p;
264-
265-
return p;
266-
}
267-
268-
p = mem_acquire(&mem_pdu.free);
269-
if (p) {
270-
pdu->pdu[last] = (void *)p;
271-
272-
return p;
273-
}
274-
275-
err = k_sem_take(&sem_pdu_free, K_FOREVER);
276-
LL_ASSERT(!err);
277-
278-
p = MFIFO_DEQUEUE(pdu_free);
279-
LL_ASSERT(p);
280-
281-
pdu->pdu[last] = (void *)p;
282-
283-
return p;
284-
}
285-
286256
struct pdu_adv *lll_adv_pdu_alloc(struct lll_adv_pdu *pdu, uint8_t *idx)
287257
{
288258
uint8_t first, last;
@@ -372,17 +342,6 @@ int lll_adv_and_extra_data_init(struct lll_adv_pdu *pdu)
372342
return 0;
373343
}
374344

375-
static inline void adv_extra_data_release(struct lll_adv_pdu *pdu, int idx)
376-
{
377-
void *extra_data;
378-
379-
extra_data = pdu->extra_data[idx];
380-
if (extra_data) {
381-
pdu->extra_data[idx] = NULL;
382-
mem_release(extra_data, &mem_extra_data.free);
383-
}
384-
}
385-
386345
int lll_adv_and_extra_data_release(struct lll_adv_pdu *pdu)
387346
{
388347
uint8_t last;
@@ -410,46 +369,6 @@ int lll_adv_and_extra_data_release(struct lll_adv_pdu *pdu)
410369
return 0;
411370
}
412371

413-
static inline void *adv_extra_data_allocate(struct lll_adv_pdu *pdu,
414-
uint8_t last)
415-
{
416-
void *extra_data;
417-
int err;
418-
419-
extra_data = pdu->extra_data[last];
420-
if (extra_data) {
421-
return extra_data;
422-
}
423-
424-
extra_data = MFIFO_DEQUEUE_PEEK(extra_data_free);
425-
if (extra_data) {
426-
err = k_sem_take(&sem_extra_data_free, K_NO_WAIT);
427-
LL_ASSERT(!err);
428-
429-
MFIFO_DEQUEUE(extra_data_free);
430-
pdu->extra_data[last] = extra_data;
431-
432-
return extra_data;
433-
}
434-
435-
extra_data = mem_acquire(&mem_extra_data.free);
436-
if (extra_data) {
437-
pdu->extra_data[last] = extra_data;
438-
439-
return extra_data;
440-
}
441-
442-
err = k_sem_take(&sem_extra_data_free, K_FOREVER);
443-
LL_ASSERT(!err);
444-
445-
extra_data = MFIFO_DEQUEUE(extra_data_free);
446-
LL_ASSERT(extra_data);
447-
448-
pdu->extra_data[last] = (void *)extra_data;
449-
450-
return extra_data;
451-
}
452-
453372
struct pdu_adv *lll_adv_pdu_and_extra_data_alloc(struct lll_adv_pdu *pdu,
454373
void **extra_data,
455374
uint8_t *idx)
@@ -468,7 +387,7 @@ struct pdu_adv *lll_adv_pdu_and_extra_data_alloc(struct lll_adv_pdu *pdu,
468387
uint8_t first_latest;
469388

470389
pdu->last = first;
471-
cpu_dsb();
390+
cpu_dmb();
472391
first_latest = pdu->first;
473392
if (first_latest != first) {
474393
last++;
@@ -485,7 +404,18 @@ struct pdu_adv *lll_adv_pdu_and_extra_data_alloc(struct lll_adv_pdu *pdu,
485404
if (extra_data) {
486405
*extra_data = adv_extra_data_allocate(pdu, last);
487406
} else {
488-
pdu->extra_data[last] = NULL;
407+
if (adv_extra_data_free(pdu, last)) {
408+
LL_ASSERT(false);
409+
410+
/* There is no release of memory allocated by
411+
* adv_pdu_allocate because there is no memory leak.
412+
* If caller can recover from this error and subsequent
413+
* call to this function occures, no new memory will be
414+
* allocated. adv_pdu_allocate will return already
415+
* allocated memory.
416+
*/
417+
return NULL;
418+
}
489419
}
490420

491421
return p;
@@ -517,8 +447,9 @@ struct pdu_adv *lll_adv_pdu_and_extra_data_latest_get(struct lll_adv_pdu *pdu,
517447
if (ed && (!MFIFO_ENQUEUE_IDX_GET(extra_data_free,
518448
&ed_free_idx))) {
519449
LL_ASSERT(false);
520-
/* ToDo what if enqueue fails and assert does not fire?
521-
* pdu_free_idx should be released before return.
450+
/* No pdu_free_idx clean up is required, sobsequent
451+
* calls to MFIFO_ENQUEUE_IDX_GET return ther same
452+
* index to memory that is in limbo state.
522453
*/
523454
return NULL;
524455
}
@@ -682,6 +613,121 @@ static int init_reset(void)
682613
return 0;
683614
}
684615

616+
static struct pdu_adv *adv_pdu_allocate(struct lll_adv_pdu *pdu, uint8_t last)
617+
{
618+
void *p;
619+
int err;
620+
621+
p = (void *)pdu->pdu[last];
622+
if (p) {
623+
return p;
624+
}
625+
626+
p = MFIFO_DEQUEUE_PEEK(pdu_free);
627+
if (p) {
628+
err = k_sem_take(&sem_pdu_free, K_NO_WAIT);
629+
LL_ASSERT(!err);
630+
631+
MFIFO_DEQUEUE(pdu_free);
632+
pdu->pdu[last] = (void *)p;
633+
634+
return p;
635+
}
636+
637+
p = mem_acquire(&mem_pdu.free);
638+
if (p) {
639+
pdu->pdu[last] = (void *)p;
640+
641+
return p;
642+
}
643+
644+
err = k_sem_take(&sem_pdu_free, K_FOREVER);
645+
LL_ASSERT(!err);
646+
647+
p = MFIFO_DEQUEUE(pdu_free);
648+
LL_ASSERT(p);
649+
650+
pdu->pdu[last] = (void *)p;
651+
652+
return p;
653+
}
654+
655+
#if IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY)
656+
static void *adv_extra_data_allocate(struct lll_adv_pdu *pdu, uint8_t last)
657+
{
658+
void *extra_data;
659+
int err;
660+
661+
extra_data = pdu->extra_data[last];
662+
if (extra_data) {
663+
return extra_data;
664+
}
665+
666+
extra_data = MFIFO_DEQUEUE_PEEK(extra_data_free);
667+
if (extra_data) {
668+
err = k_sem_take(&sem_extra_data_free, K_NO_WAIT);
669+
LL_ASSERT(!err);
670+
671+
MFIFO_DEQUEUE(extra_data_free);
672+
pdu->extra_data[last] = extra_data;
673+
674+
return extra_data;
675+
}
676+
677+
extra_data = mem_acquire(&mem_extra_data.free);
678+
if (extra_data) {
679+
pdu->extra_data[last] = extra_data;
680+
681+
return extra_data;
682+
}
683+
684+
err = k_sem_take(&sem_extra_data_free, K_FOREVER);
685+
LL_ASSERT(!err);
686+
687+
extra_data = MFIFO_DEQUEUE(extra_data_free);
688+
LL_ASSERT(extra_data);
689+
690+
pdu->extra_data[last] = (void *)extra_data;
691+
692+
return extra_data;
693+
}
694+
695+
static int adv_extra_data_free(struct lll_adv_pdu *pdu, uint8_t last)
696+
{
697+
uint8_t ed_free_idx;
698+
void *ed;
699+
700+
ed = pdu->extra_data[last];
701+
702+
if (ed) {
703+
if (!MFIFO_ENQUEUE_IDX_GET(extra_data_free, &ed_free_idx)) {
704+
LL_ASSERT(false);
705+
/* ToDo what if enqueue fails and assert does not fire?
706+
* pdu_free_idx should be released before return.
707+
*/
708+
return -ENOMEM;
709+
}
710+
pdu->extra_data[last] = NULL;
711+
712+
MFIFO_BY_IDX_ENQUEUE(extra_data_free, ed_free_idx, ed);
713+
k_sem_give(&sem_extra_data_free);
714+
}
715+
716+
return 0;
717+
}
718+
719+
static inline void adv_extra_data_release(struct lll_adv_pdu *pdu, int idx)
720+
{
721+
void *extra_data;
722+
723+
extra_data = pdu->extra_data[idx];
724+
if (extra_data) {
725+
pdu->extra_data[idx] = NULL;
726+
mem_release(extra_data, &mem_extra_data.free);
727+
}
728+
}
729+
#endif /* CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY */
730+
685731
static int prepare_cb(struct lll_prepare_param *p)
686732
{
687733
uint32_t ticks_at_event;

0 commit comments

Comments
 (0)