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 <piotr.pryga@nordicsemi.no>
This commit is contained in:
parent
41c4af1ba3
commit
f3e04898eb
9 changed files with 254 additions and 15 deletions
|
@ -8,10 +8,18 @@ config BT_CTLR_DF_SUPPORT
|
|||
select BT_CTLR_DF_CTE_TX_SUPPORT
|
||||
select BT_CTLR_DF_ANT_SWITCH_2US_SUPPORT
|
||||
select BT_CTLR_DF_ANT_SWITCH_1US_SUPPORT
|
||||
select BT_CTLR_DF_CTE_RX_SUPPORT
|
||||
select BT_CTLR_DF_CTE_RX_SAMPLE_1US_SUPPORT
|
||||
|
||||
config BT_CTLR_DF_CTE_TX_SUPPORT
|
||||
bool
|
||||
|
||||
config BT_CTLR_DF_CTE_RX_SUPPORT
|
||||
bool
|
||||
|
||||
config BT_CTLR_DF_CTE_RX_SAMPLE_1US_SUPPORT
|
||||
bool
|
||||
|
||||
config BT_CTLR_DF_ANT_SWITCH_2US_SUPPORT
|
||||
bool
|
||||
|
||||
|
@ -37,6 +45,16 @@ config BT_CTLR_DF_CTE_TX
|
|||
Enable support for transmission of Constant Tone Extension in
|
||||
controller.
|
||||
|
||||
config BT_CTLR_DF_CTE_RX_SAMPLE_1US
|
||||
bool "Enable reception of CTE with 1us sampling slots"
|
||||
depends on BT_CTLR_DF_CTE_RX_SAMPLE_1US_SUPPORT
|
||||
default y
|
||||
help
|
||||
Enable reception of Constant Tone Extension. Process IQ sampling
|
||||
during CTE reception with 1us sampling slots.
|
||||
This sampling mode is optional for Direction Finding according to
|
||||
Bluetooth v5.1.
|
||||
|
||||
config BT_CTLR_DF_ANT_SWITCH_1US
|
||||
bool "Enable support for 1us antenna switch slots"
|
||||
depends on BT_CTLR_DF_ANT_SWITCH_1US_SUPPORT
|
||||
|
@ -56,6 +74,21 @@ config BT_CTLR_DF_ANT_SWITCH_TX
|
|||
Enable support for antenna switching during CTE transmission.
|
||||
Also known as Angle of Departure mode.
|
||||
|
||||
config BT_CTLR_DF_ANT_SWITCH_RX
|
||||
bool "Enable antenna switching during CTE reception (AoA) feature"
|
||||
depends on BT_CTLR_DF_ANT_SWITCH_2US_SUPPORT
|
||||
default y
|
||||
help
|
||||
Enable support for antenna switching during CTE reception.
|
||||
Also known as Angle of Arrival mode.
|
||||
|
||||
config BT_CTLR_DF_CTE_RX
|
||||
bool "Enable reception of Constant Tone Extension feature"
|
||||
depends on BT_CTLR_DF_CTE_RX_SUPPORT
|
||||
default y
|
||||
help
|
||||
Enable support for reception of Constant Tone Extension in controller.
|
||||
|
||||
config BT_CTLR_DF_CONN_CTE_RSP
|
||||
bool "Enable Connection CTE Response feature"
|
||||
depends on BT_CTLR_DF_CTE_TX && BT_CONN
|
||||
|
@ -80,9 +113,10 @@ config BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN
|
|||
range 2 75 if !SOC_COMPATIBLE_NRF
|
||||
default 12
|
||||
help
|
||||
Defines maximum number of antenna switch patterns that controller
|
||||
will store. For nRF5x-based controllers, the hardware imposes
|
||||
the value is within range 3 to 40. For general use cases Bluetoot
|
||||
Core 5.1 spec. requires the value to be within range 2 up to 75.
|
||||
Defines maximum length of antenna switch pattern that controller
|
||||
is able to store. For nRF5x-based controllers, the hardware imposes
|
||||
the value is within range 3 to 40, where last value is maximum.
|
||||
For general use cases Bluetooth Core 5.1 spec. required the value
|
||||
to be within range 2 up to 75.
|
||||
|
||||
endif # BT_CTLR_DF
|
||||
|
|
9
subsys/bluetooth/controller/hal/radio_df.h
Normal file
9
subsys/bluetooth/controller/hal/radio_df.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_DF)
|
||||
#include "hal/radio_df_vendor_hal.h"
|
||||
#endif /* CONFIG_BT_CTLR_DF */
|
|
@ -18,3 +18,9 @@ struct lll_df_adv_cfg {
|
|||
|
||||
/* @brief Min supported length of antenna switching pattern */
|
||||
#define LLL_DF_MIN_ANT_PATTERN_LEN 3
|
||||
|
||||
/* @brief Max supported CTE length in 8us units */
|
||||
#define LLL_DF_MAX_CTE_LEN 20
|
||||
|
||||
/* Provides number of available antennas for Direction Finding */
|
||||
uint8_t lll_df_ant_num_get(void);
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <devicetree.h>
|
||||
#include <sys/util_macro.h>
|
||||
#include <nrfx/hal/nrf_radio.h>
|
||||
|
||||
#include "radio_df.h"
|
||||
|
||||
/* @brief Minimum antennas number required if antenna switching is enabled */
|
||||
#define DF_ANT_NUM_MIN 2
|
||||
/* @brief Value to set antenna GPIO pin as not connected */
|
||||
#define DF_GPIO_PIN_NOT_SET 0xFF
|
||||
/* @brief Number of PSEL_DFEGPIO registers in Radio peripheral */
|
||||
#define DF_PSEL_GPIO_NUM 8
|
||||
|
||||
/* @brief Direction Finding antenna matrix configuration */
|
||||
struct df_ant_cfg {
|
||||
uint8_t ant_num;
|
||||
/* Selection of GPIOs to be used to switch antennas by Radio */
|
||||
uint8_t dfe_gpio[DF_PSEL_GPIO_NUM];
|
||||
};
|
||||
|
||||
#define RADIO DT_NODELABEL(radio)
|
||||
#define DFE_GPIO_PIN(idx) \
|
||||
COND_CODE_1(DT_NODE_HAS_PROP(RADIO, dfegpio##idx##_gpios), \
|
||||
(NRF_DT_GPIOS_TO_PSEL(RADIO, dfegpio##idx##_gpios)), \
|
||||
(DF_GPIO_PIN_NOT_SET))
|
||||
|
||||
#define DFE_GPIO_PIN_DISCONNECT (RADIO_PSEL_DFEGPIO_CONNECT_Disconnected << \
|
||||
RADIO_PSEL_DFEGPIO_CONNECT_Pos)
|
||||
|
||||
#define COUNT_GPIO(idx, _) + DT_NODE_HAS_PROP(RADIO, dfegpio##idx##_gpios)
|
||||
#define DFE_GPIO_NUM (UTIL_LISTIFY(DF_PSEL_GPIO_NUM, COUNT_GPIO, _))
|
||||
|
||||
/* DFE_GPIO_NUM_IS_ZERO is required to correctly compile COND_CODE_1 in
|
||||
* DFE_GPIO_ALLOWED_ANT_NUM macro. DFE_GPIO_NUM does not expand to literal 1
|
||||
* So it is not possible to use it as a conditional in COND_CODE_1 argument.
|
||||
*/
|
||||
#if (DFE_GPIO_NUM > 0)
|
||||
#define DFE_GPIO_NUM_IS_ZERO 1
|
||||
#else
|
||||
#define DFE_GPIO_NUM_IS_ZERO EMPTY
|
||||
#endif
|
||||
|
||||
#define DFE_GPIO_ALLOWED_ANT_NUM COND_CODE_1(DFE_GPIO_NUM_IS_ZERO, \
|
||||
(BIT(DFE_GPIO_NUM)), (0))
|
||||
|
||||
#if IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_TX) || \
|
||||
IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_RX)
|
||||
|
||||
/* Check if there is enough pins configured to represent each pattern
|
||||
* for given antennas number.
|
||||
*/
|
||||
BUILD_ASSERT((DT_PROP(RADIO, dfe_ant_num) <= DFE_GPIO_ALLOWED_ANT_NUM), "Insufficient "
|
||||
"number of GPIO pins configured.");
|
||||
BUILD_ASSERT((DT_PROP(RADIO, dfe_ant_num) >= DF_ANT_NUM_MIN), "Insufficient "
|
||||
"number of antennas provided.");
|
||||
|
||||
/* Check if dfegpio#-gios property has flag cell set to zero */
|
||||
#define DFE_GPIO_PIN_FLAGS(idx) (DT_GPIO_FLAGS(RADIO, dfegpio##idx##_gpios))
|
||||
#define DFE_GPIO_PIN_IS_FLAG_ZERO(idx) \
|
||||
COND_CODE_1(DT_NODE_HAS_PROP(RADIO, dfegpio##idx##_gpios), \
|
||||
(BUILD_ASSERT((DFE_GPIO_PIN_FLAGS(idx) == 0), \
|
||||
"Flags value of GPIO pin property must be" \
|
||||
"zero.")), \
|
||||
(EMPTY))
|
||||
|
||||
#define DFE_GPIO_PIN_LIST(idx, _) idx,
|
||||
FOR_EACH(DFE_GPIO_PIN_IS_FLAG_ZERO, (;),
|
||||
UTIL_LISTIFY(DF_PSEL_GPIO_NUM, DFE_GPIO_PIN_LIST))
|
||||
|
||||
#if DT_NODE_HAS_STATUS(RADIO, okay)
|
||||
const static struct df_ant_cfg ant_cfg = {
|
||||
.ant_num = DT_PROP(RADIO, dfe_ant_num),
|
||||
.dfe_gpio = {
|
||||
DFE_GPIO_PIN(0),
|
||||
DFE_GPIO_PIN(1),
|
||||
DFE_GPIO_PIN(2),
|
||||
DFE_GPIO_PIN(3),
|
||||
DFE_GPIO_PIN(4),
|
||||
DFE_GPIO_PIN(5),
|
||||
DFE_GPIO_PIN(6),
|
||||
DFE_GPIO_PIN(7),
|
||||
}
|
||||
};
|
||||
#else
|
||||
#error "DF antenna switching feature requires dfe_ant to be enabled in DTS"
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_BT_CTLR_DF_ANT_SWITCH_TX || CONFIG_BT_CTLR_DF_ANT_SWITCH_RX */
|
||||
|
||||
/* @brief Function performs steps related with DF antennas configuration.
|
||||
*
|
||||
* Sets up DF related PSEL.DFEGPIO registers to give possibility to Radio
|
||||
* to drivee antennas switches.
|
||||
*/
|
||||
void radio_df_ant_configure(void)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_TX) || \
|
||||
IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_RX)
|
||||
|
||||
for (uint8_t idx = 0; idx < DF_PSEL_GPIO_NUM; ++idx) {
|
||||
if (ant_cfg.dfe_gpio[idx] != DF_GPIO_PIN_NOT_SET) {
|
||||
nrf_radio_dfe_pattern_pin_set(NRF_RADIO,
|
||||
ant_cfg.dfe_gpio[idx],
|
||||
idx);
|
||||
} else {
|
||||
nrf_radio_dfe_pattern_pin_set(NRF_RADIO,
|
||||
DFE_GPIO_PIN_DISCONNECT,
|
||||
idx);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_DF_ANT_SWITCH_TX || CONFIG_BT_CTLR_DF_ANT_SWITCH_RX */
|
||||
}
|
||||
|
||||
/* @brief Function provides number of available antennas for Direction Finding.
|
||||
*
|
||||
* The number of antennas is hardware defined. It is provided via devicetree.
|
||||
*
|
||||
* @return Number of available antennas.
|
||||
*/
|
||||
uint8_t radio_df_ant_num_get(void)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_TX) || \
|
||||
IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_RX)
|
||||
return ant_cfg.ant_num;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/* Performs steps related with DF antennae configuration. */
|
||||
void radio_df_ant_configure(void);
|
||||
/* Provides number of available antennae for Direction Finding */
|
||||
uint8_t radio_df_ant_num_get(void);
|
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "hal/nrf5/radio/radio_df.h"
|
20
subsys/bluetooth/controller/ll_sw/nordic/lll/lll_df.c
Normal file
20
subsys/bluetooth/controller/ll_sw/nordic/lll/lll_df.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "hal/radio_df.h"
|
||||
#include "lll_df.h"
|
||||
|
||||
/* @brief Function provides number of available antennas.
|
||||
*
|
||||
* The number of antenna is hardware defined and it is provided via devicetree.
|
||||
*
|
||||
* @return Number of available antennas.
|
||||
*/
|
||||
uint8_t lll_df_ant_num_get(void)
|
||||
{
|
||||
return radio_df_ant_num_get();
|
||||
}
|
|
@ -52,6 +52,11 @@ if(CONFIG_BT_LL_SW_SPLIT)
|
|||
CONFIG_BT_CTLR_PROFILE_ISR
|
||||
ll_sw/nordic/lll/lll_prof.c
|
||||
)
|
||||
zephyr_library_sources_ifdef(
|
||||
CONFIG_BT_CTLR_DF
|
||||
ll_sw/nordic/lll/lll_df.c
|
||||
ll_sw/nordic/hal/nrf5/radio/radio_df.c
|
||||
)
|
||||
zephyr_library_include_directories(
|
||||
ll_sw/nordic/lll
|
||||
)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Nordic Semiconductor ASA
|
||||
* Copyright (c) 2020 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -237,14 +237,14 @@ uint8_t ll_df_set_conn_cte_tx_params(uint16_t handle, uint8_t cte_types,
|
|||
}
|
||||
|
||||
/* @brief Function provides information about Direction Finding
|
||||
* antennae switching and sampling related settings.
|
||||
* antennas switching and sampling related settings.
|
||||
*
|
||||
* @param[out]switch_sample_rates Pointer to store available antennae
|
||||
* @param[out]switch_sample_rates Pointer to store available antennas
|
||||
* switch-sampling configurations.
|
||||
* @param[out]num_ant Pointer to store number of available
|
||||
* antennae.
|
||||
* antennas.
|
||||
* @param[out]max_switch_pattern_len Pointer to store maximum number of
|
||||
* antennae switch patterns.
|
||||
* antennas ids in switch pattern.
|
||||
* @param[out]max_cte_len Pointer to store maximum length of CTE
|
||||
* in [8us] units.
|
||||
*/
|
||||
|
@ -253,13 +253,25 @@ void ll_df_read_ant_inf(uint8_t *switch_sample_rates,
|
|||
uint8_t *max_switch_pattern_len,
|
||||
uint8_t *max_cte_len)
|
||||
{
|
||||
/* Currently filled with data that inform about
|
||||
* lack of antenna support for Direction Finding
|
||||
*/
|
||||
*switch_sample_rates = 0;
|
||||
*num_ant = 0;
|
||||
*max_switch_pattern_len = 0;
|
||||
*max_cte_len = 0;
|
||||
if (IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_TX) &&
|
||||
IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_1US)) {
|
||||
*switch_sample_rates |= DF_AOD_1US_TX;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_CTLR_DF_CTE_RX) &&
|
||||
IS_ENABLED(CONFIG_BT_CTLR_DF_CTE_RX_SAMPLE_1US)) {
|
||||
*switch_sample_rates |= DF_AOD_1US_RX;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_RX) &&
|
||||
IS_ENABLED(CONFIG_BT_CTLR_DF_CTE_RX_SAMPLE_1US)) {
|
||||
*switch_sample_rates |= DF_AOA_1US;
|
||||
}
|
||||
|
||||
*max_switch_pattern_len = CONFIG_BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN;
|
||||
*num_ant = lll_df_ant_num_get();
|
||||
*max_cte_len = LLL_DF_MAX_CTE_LEN;
|
||||
}
|
||||
|
||||
static struct lll_df_adv_cfg *ull_df_adv_cfg_acquire(void)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue