Skip to content

Commit f3e0489

Browse files
ppryga-nordiccarlescufi
authored andcommitted
Bluetooth: controller: ll_sw: nordic: Add DF antenna configuration handling
Add support for Direction Finding antenna configuration in Nordic hal of Bluetooth controller. Add handling of response for HCI_LE_Read_Antenna_Information HCI command in controller (upper and lower link layer). Handling of response to the command requires antenna matrix configuration. Signed-off-by: Piotr Pryga <[email protected]>
1 parent 41c4af1 commit f3e0489

File tree

9 files changed

+254
-15
lines changed

9 files changed

+254
-15
lines changed

subsys/bluetooth/controller/Kconfig.df

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,18 @@ config BT_CTLR_DF_SUPPORT
88
select BT_CTLR_DF_CTE_TX_SUPPORT
99
select BT_CTLR_DF_ANT_SWITCH_2US_SUPPORT
1010
select BT_CTLR_DF_ANT_SWITCH_1US_SUPPORT
11+
select BT_CTLR_DF_CTE_RX_SUPPORT
12+
select BT_CTLR_DF_CTE_RX_SAMPLE_1US_SUPPORT
1113

1214
config BT_CTLR_DF_CTE_TX_SUPPORT
1315
bool
1416

17+
config BT_CTLR_DF_CTE_RX_SUPPORT
18+
bool
19+
20+
config BT_CTLR_DF_CTE_RX_SAMPLE_1US_SUPPORT
21+
bool
22+
1523
config BT_CTLR_DF_ANT_SWITCH_2US_SUPPORT
1624
bool
1725

@@ -37,6 +45,16 @@ config BT_CTLR_DF_CTE_TX
3745
Enable support for transmission of Constant Tone Extension in
3846
controller.
3947

48+
config BT_CTLR_DF_CTE_RX_SAMPLE_1US
49+
bool "Enable reception of CTE with 1us sampling slots"
50+
depends on BT_CTLR_DF_CTE_RX_SAMPLE_1US_SUPPORT
51+
default y
52+
help
53+
Enable reception of Constant Tone Extension. Process IQ sampling
54+
during CTE reception with 1us sampling slots.
55+
This sampling mode is optional for Direction Finding according to
56+
Bluetooth v5.1.
57+
4058
config BT_CTLR_DF_ANT_SWITCH_1US
4159
bool "Enable support for 1us antenna switch slots"
4260
depends on BT_CTLR_DF_ANT_SWITCH_1US_SUPPORT
@@ -56,6 +74,21 @@ config BT_CTLR_DF_ANT_SWITCH_TX
5674
Enable support for antenna switching during CTE transmission.
5775
Also known as Angle of Departure mode.
5876

77+
config BT_CTLR_DF_ANT_SWITCH_RX
78+
bool "Enable antenna switching during CTE reception (AoA) feature"
79+
depends on BT_CTLR_DF_ANT_SWITCH_2US_SUPPORT
80+
default y
81+
help
82+
Enable support for antenna switching during CTE reception.
83+
Also known as Angle of Arrival mode.
84+
85+
config BT_CTLR_DF_CTE_RX
86+
bool "Enable reception of Constant Tone Extension feature"
87+
depends on BT_CTLR_DF_CTE_RX_SUPPORT
88+
default y
89+
help
90+
Enable support for reception of Constant Tone Extension in controller.
91+
5992
config BT_CTLR_DF_CONN_CTE_RSP
6093
bool "Enable Connection CTE Response feature"
6194
depends on BT_CTLR_DF_CTE_TX && BT_CONN
@@ -80,9 +113,10 @@ config BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN
80113
range 2 75 if !SOC_COMPATIBLE_NRF
81114
default 12
82115
help
83-
Defines maximum number of antenna switch patterns that controller
84-
will store. For nRF5x-based controllers, the hardware imposes
85-
the value is within range 3 to 40. For general use cases Bluetoot
86-
Core 5.1 spec. requires the value to be within range 2 up to 75.
116+
Defines maximum length of antenna switch pattern that controller
117+
is able to store. For nRF5x-based controllers, the hardware imposes
118+
the value is within range 3 to 40, where last value is maximum.
119+
For general use cases Bluetooth Core 5.1 spec. required the value
120+
to be within range 2 up to 75.
87121

88122
endif # BT_CTLR_DF
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*
2+
* Copyright (c) 2020 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#if defined(CONFIG_BT_CTLR_DF)
8+
#include "hal/radio_df_vendor_hal.h"
9+
#endif /* CONFIG_BT_CTLR_DF */

subsys/bluetooth/controller/ll_sw/lll_df.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,9 @@ struct lll_df_adv_cfg {
1818

1919
/* @brief Min supported length of antenna switching pattern */
2020
#define LLL_DF_MIN_ANT_PATTERN_LEN 3
21+
22+
/* @brief Max supported CTE length in 8us units */
23+
#define LLL_DF_MAX_CTE_LEN 20
24+
25+
/* Provides number of available antennas for Direction Finding */
26+
uint8_t lll_df_ant_num_get(void);
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*
2+
* Copyright (c) 2020 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <stdint.h>
8+
#include <errno.h>
9+
#include <devicetree.h>
10+
#include <sys/util_macro.h>
11+
#include <nrfx/hal/nrf_radio.h>
12+
13+
#include "radio_df.h"
14+
15+
/* @brief Minimum antennas number required if antenna switching is enabled */
16+
#define DF_ANT_NUM_MIN 2
17+
/* @brief Value to set antenna GPIO pin as not connected */
18+
#define DF_GPIO_PIN_NOT_SET 0xFF
19+
/* @brief Number of PSEL_DFEGPIO registers in Radio peripheral */
20+
#define DF_PSEL_GPIO_NUM 8
21+
22+
/* @brief Direction Finding antenna matrix configuration */
23+
struct df_ant_cfg {
24+
uint8_t ant_num;
25+
/* Selection of GPIOs to be used to switch antennas by Radio */
26+
uint8_t dfe_gpio[DF_PSEL_GPIO_NUM];
27+
};
28+
29+
#define RADIO DT_NODELABEL(radio)
30+
#define DFE_GPIO_PIN(idx) \
31+
COND_CODE_1(DT_NODE_HAS_PROP(RADIO, dfegpio##idx##_gpios), \
32+
(NRF_DT_GPIOS_TO_PSEL(RADIO, dfegpio##idx##_gpios)), \
33+
(DF_GPIO_PIN_NOT_SET))
34+
35+
#define DFE_GPIO_PIN_DISCONNECT (RADIO_PSEL_DFEGPIO_CONNECT_Disconnected << \
36+
RADIO_PSEL_DFEGPIO_CONNECT_Pos)
37+
38+
#define COUNT_GPIO(idx, _) + DT_NODE_HAS_PROP(RADIO, dfegpio##idx##_gpios)
39+
#define DFE_GPIO_NUM (UTIL_LISTIFY(DF_PSEL_GPIO_NUM, COUNT_GPIO, _))
40+
41+
/* DFE_GPIO_NUM_IS_ZERO is required to correctly compile COND_CODE_1 in
42+
* DFE_GPIO_ALLOWED_ANT_NUM macro. DFE_GPIO_NUM does not expand to literal 1
43+
* So it is not possible to use it as a conditional in COND_CODE_1 argument.
44+
*/
45+
#if (DFE_GPIO_NUM > 0)
46+
#define DFE_GPIO_NUM_IS_ZERO 1
47+
#else
48+
#define DFE_GPIO_NUM_IS_ZERO EMPTY
49+
#endif
50+
51+
#define DFE_GPIO_ALLOWED_ANT_NUM COND_CODE_1(DFE_GPIO_NUM_IS_ZERO, \
52+
(BIT(DFE_GPIO_NUM)), (0))
53+
54+
#if IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_TX) || \
55+
IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_RX)
56+
57+
/* Check if there is enough pins configured to represent each pattern
58+
* for given antennas number.
59+
*/
60+
BUILD_ASSERT((DT_PROP(RADIO, dfe_ant_num) <= DFE_GPIO_ALLOWED_ANT_NUM), "Insufficient "
61+
"number of GPIO pins configured.");
62+
BUILD_ASSERT((DT_PROP(RADIO, dfe_ant_num) >= DF_ANT_NUM_MIN), "Insufficient "
63+
"number of antennas provided.");
64+
65+
/* Check if dfegpio#-gios property has flag cell set to zero */
66+
#define DFE_GPIO_PIN_FLAGS(idx) (DT_GPIO_FLAGS(RADIO, dfegpio##idx##_gpios))
67+
#define DFE_GPIO_PIN_IS_FLAG_ZERO(idx) \
68+
COND_CODE_1(DT_NODE_HAS_PROP(RADIO, dfegpio##idx##_gpios), \
69+
(BUILD_ASSERT((DFE_GPIO_PIN_FLAGS(idx) == 0), \
70+
"Flags value of GPIO pin property must be" \
71+
"zero.")), \
72+
(EMPTY))
73+
74+
#define DFE_GPIO_PIN_LIST(idx, _) idx,
75+
FOR_EACH(DFE_GPIO_PIN_IS_FLAG_ZERO, (;),
76+
UTIL_LISTIFY(DF_PSEL_GPIO_NUM, DFE_GPIO_PIN_LIST))
77+
78+
#if DT_NODE_HAS_STATUS(RADIO, okay)
79+
const static struct df_ant_cfg ant_cfg = {
80+
.ant_num = DT_PROP(RADIO, dfe_ant_num),
81+
.dfe_gpio = {
82+
DFE_GPIO_PIN(0),
83+
DFE_GPIO_PIN(1),
84+
DFE_GPIO_PIN(2),
85+
DFE_GPIO_PIN(3),
86+
DFE_GPIO_PIN(4),
87+
DFE_GPIO_PIN(5),
88+
DFE_GPIO_PIN(6),
89+
DFE_GPIO_PIN(7),
90+
}
91+
};
92+
#else
93+
#error "DF antenna switching feature requires dfe_ant to be enabled in DTS"
94+
#endif
95+
96+
#endif /* CONFIG_BT_CTLR_DF_ANT_SWITCH_TX || CONFIG_BT_CTLR_DF_ANT_SWITCH_RX */
97+
98+
/* @brief Function performs steps related with DF antennas configuration.
99+
*
100+
* Sets up DF related PSEL.DFEGPIO registers to give possibility to Radio
101+
* to drivee antennas switches.
102+
*/
103+
void radio_df_ant_configure(void)
104+
{
105+
#if IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_TX) || \
106+
IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_RX)
107+
108+
for (uint8_t idx = 0; idx < DF_PSEL_GPIO_NUM; ++idx) {
109+
if (ant_cfg.dfe_gpio[idx] != DF_GPIO_PIN_NOT_SET) {
110+
nrf_radio_dfe_pattern_pin_set(NRF_RADIO,
111+
ant_cfg.dfe_gpio[idx],
112+
idx);
113+
} else {
114+
nrf_radio_dfe_pattern_pin_set(NRF_RADIO,
115+
DFE_GPIO_PIN_DISCONNECT,
116+
idx);
117+
}
118+
}
119+
#endif /* CONFIG_BT_CTLR_DF_ANT_SWITCH_TX || CONFIG_BT_CTLR_DF_ANT_SWITCH_RX */
120+
}
121+
122+
/* @brief Function provides number of available antennas for Direction Finding.
123+
*
124+
* The number of antennas is hardware defined. It is provided via devicetree.
125+
*
126+
* @return Number of available antennas.
127+
*/
128+
uint8_t radio_df_ant_num_get(void)
129+
{
130+
#if IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_TX) || \
131+
IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_RX)
132+
return ant_cfg.ant_num;
133+
#else
134+
return 0;
135+
#endif
136+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/*
2+
* Copyright (c) 2020 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/* Performs steps related with DF antennae configuration. */
8+
void radio_df_ant_configure(void);
9+
/* Provides number of available antennae for Direction Finding */
10+
uint8_t radio_df_ant_num_get(void);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/*
2+
* Copyright (c) 2020 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include "hal/nrf5/radio/radio_df.h"
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright (c) 2020 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <stdint.h>
8+
#include "hal/radio_df.h"
9+
#include "lll_df.h"
10+
11+
/* @brief Function provides number of available antennas.
12+
*
13+
* The number of antenna is hardware defined and it is provided via devicetree.
14+
*
15+
* @return Number of available antennas.
16+
*/
17+
uint8_t lll_df_ant_num_get(void)
18+
{
19+
return radio_df_ant_num_get();
20+
}

subsys/bluetooth/controller/ll_sw/nrf.cmake

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ if(CONFIG_BT_LL_SW_SPLIT)
5252
CONFIG_BT_CTLR_PROFILE_ISR
5353
ll_sw/nordic/lll/lll_prof.c
5454
)
55+
zephyr_library_sources_ifdef(
56+
CONFIG_BT_CTLR_DF
57+
ll_sw/nordic/lll/lll_df.c
58+
ll_sw/nordic/hal/nrf5/radio/radio_df.c
59+
)
5560
zephyr_library_include_directories(
5661
ll_sw/nordic/lll
5762
)

subsys/bluetooth/controller/ll_sw/ull_df.c

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018-2020 Nordic Semiconductor ASA
2+
* Copyright (c) 2020 Nordic Semiconductor ASA
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -237,14 +237,14 @@ uint8_t ll_df_set_conn_cte_tx_params(uint16_t handle, uint8_t cte_types,
237237
}
238238

239239
/* @brief Function provides information about Direction Finding
240-
* antennae switching and sampling related settings.
240+
* antennas switching and sampling related settings.
241241
*
242-
* @param[out]switch_sample_rates Pointer to store available antennae
242+
* @param[out]switch_sample_rates Pointer to store available antennas
243243
* switch-sampling configurations.
244244
* @param[out]num_ant Pointer to store number of available
245-
* antennae.
245+
* antennas.
246246
* @param[out]max_switch_pattern_len Pointer to store maximum number of
247-
* antennae switch patterns.
247+
* antennas ids in switch pattern.
248248
* @param[out]max_cte_len Pointer to store maximum length of CTE
249249
* in [8us] units.
250250
*/
@@ -253,13 +253,25 @@ void ll_df_read_ant_inf(uint8_t *switch_sample_rates,
253253
uint8_t *max_switch_pattern_len,
254254
uint8_t *max_cte_len)
255255
{
256-
/* Currently filled with data that inform about
257-
* lack of antenna support for Direction Finding
258-
*/
259256
*switch_sample_rates = 0;
260-
*num_ant = 0;
261-
*max_switch_pattern_len = 0;
262-
*max_cte_len = 0;
257+
if (IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_TX) &&
258+
IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_1US)) {
259+
*switch_sample_rates |= DF_AOD_1US_TX;
260+
}
261+
262+
if (IS_ENABLED(CONFIG_BT_CTLR_DF_CTE_RX) &&
263+
IS_ENABLED(CONFIG_BT_CTLR_DF_CTE_RX_SAMPLE_1US)) {
264+
*switch_sample_rates |= DF_AOD_1US_RX;
265+
}
266+
267+
if (IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_RX) &&
268+
IS_ENABLED(CONFIG_BT_CTLR_DF_CTE_RX_SAMPLE_1US)) {
269+
*switch_sample_rates |= DF_AOA_1US;
270+
}
271+
272+
*max_switch_pattern_len = CONFIG_BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN;
273+
*num_ant = lll_df_ant_num_get();
274+
*max_cte_len = LLL_DF_MAX_CTE_LEN;
263275
}
264276

265277
static struct lll_df_adv_cfg *ull_df_adv_cfg_acquire(void)

0 commit comments

Comments
 (0)