diff --git a/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840.dts b/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840.dts index 21b73dd43dc..01a756e7301 100644 --- a/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840.dts +++ b/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840.dts @@ -115,6 +115,14 @@ <5 &adc 7>; /* A5 = P0.31 = AIN7 */ }; + nrf_radio_fem: fem { + compatible = "generic-fem-two-ctrl-pins"; + ctx-gpios = <&gpio1 5 0>; + ctx-settle-time-us = <5>; + crx-gpios = <&gpio1 6 0>; + crx-settle-time-us = <5>; + }; + /* These aliases are provided for compatibility with samples */ aliases { led0 = &led0; @@ -130,6 +138,10 @@ }; }; +&radio { + fem = <&nrf_radio_fem>; +}; + &adc { status = "okay"; }; diff --git a/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840_defconfig b/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840_defconfig index ffd7ced78b4..624a2a73295 100644 --- a/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840_defconfig +++ b/boards/arm/ubx_bmd345eval_nrf52840/ubx_bmd345eval_nrf52840_defconfig @@ -28,11 +28,3 @@ CONFIG_UART_CONSOLE=y # additional board options CONFIG_GPIO_AS_PINRESET=y - -# PA GPIO Pin -CONFIG_BT_CTLR_GPIO_PA=y -CONFIG_BT_CTLR_GPIO_PA_PIN=37 - -# LNA GPIO Pin -CONFIG_BT_CTLR_GPIO_LNA=y -CONFIG_BT_CTLR_GPIO_LNA_PIN=38 diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index 4c69032dbdf..f78fbe5cecf 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -7,6 +7,8 @@ #include #include +#include +#include #include #include @@ -23,46 +25,102 @@ #include "radio_internal.h" +/* Converts the GPIO controller in a FEM property's GPIO specification + * to its nRF register map pointer. + * + * Make sure to use NRF_DT_CHECK_GPIO_CTLR_IS_SOC to check the GPIO + * controller has the right compatible wherever you use this. + */ +#define NRF_FEM_GPIO(prop) \ + ((NRF_GPIO_Type *)DT_REG_ADDR(DT_GPIO_CTLR(FEM_NODE, prop))) + +/* Converts GPIO specification to a PSEL value. */ +#define NRF_FEM_PSEL(prop) NRF_DT_GPIOS_TO_PSEL(FEM_NODE, prop) + +/* Check if GPIO flags are active low. */ +#define ACTIVE_LOW(flags) ((flags) & GPIO_ACTIVE_LOW) + +/* Check if GPIO flags contain unsupported values. */ +#define BAD_FLAGS(flags) ((flags) & ~GPIO_ACTIVE_LOW) + +/* GPIOTE OUTINIT setting for a pin's inactive level, from its + * devicetree flags. + */ +#define OUTINIT_INACTIVE(flags) \ + (ACTIVE_LOW(flags) ? \ + GPIOTE_CONFIG_OUTINIT_High : \ + GPIOTE_CONFIG_OUTINIT_Low) + +#if defined(FEM_NODE) +BUILD_ASSERT(!HAL_RADIO_GPIO_PA_OFFSET_MISSING, + "fem node " DT_NODE_PATH(FEM_NODE) " has property " + HAL_RADIO_GPIO_PA_PROP_NAME " set, so you must also set " + HAL_RADIO_GPIO_PA_OFFSET_PROP_NAME); + +BUILD_ASSERT(!HAL_RADIO_GPIO_LNA_OFFSET_MISSING, + "fem node " DT_NODE_PATH(FEM_NODE) " has property " + HAL_RADIO_GPIO_LNA_PROP_NAME " set, so you must also set " + HAL_RADIO_GPIO_LNA_OFFSET_PROP_NAME); +#endif /* FEM_NODE */ + +/* + * "Manual" conversions of devicetree values to register bits. We + * can't use the Zephyr GPIO API here, so we need this extra + * boilerplate. + */ + #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) -#if ((CONFIG_BT_CTLR_GPIO_PA_PIN) > 31) -#define NRF_GPIO_PA NRF_P1 -#define NRF_GPIO_PA_PIN ((CONFIG_BT_CTLR_GPIO_PA_PIN) - 32) -#else -#define NRF_GPIO_PA NRF_P0 -#define NRF_GPIO_PA_PIN CONFIG_BT_CTLR_GPIO_PA_PIN -#endif +#define NRF_GPIO_PA NRF_FEM_GPIO(HAL_RADIO_GPIO_PA_PROP) +#define NRF_GPIO_PA_PIN DT_GPIO_PIN(FEM_NODE, HAL_RADIO_GPIO_PA_PROP) +#define NRF_GPIO_PA_FLAGS DT_GPIO_FLAGS(FEM_NODE, HAL_RADIO_GPIO_PA_PROP) +#define NRF_GPIO_PA_PSEL NRF_FEM_PSEL(HAL_RADIO_GPIO_PA_PROP) +NRF_DT_CHECK_GPIO_CTLR_IS_SOC(FEM_NODE, HAL_RADIO_GPIO_PA_PROP, + HAL_RADIO_GPIO_PA_PROP_NAME); +BUILD_ASSERT(!BAD_FLAGS(NRF_GPIO_PA_FLAGS), + "fem node " DT_NODE_PATH(FEM_NODE) " has invalid GPIO flags in " + HAL_RADIO_GPIO_PA_PROP_NAME + "; only GPIO_ACTIVE_LOW or GPIO_ACTIVE_HIGH are supported"); #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */ #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN) -#if ((CONFIG_BT_CTLR_GPIO_LNA_PIN) > 31) -#define NRF_GPIO_LNA NRF_P1 -#define NRF_GPIO_LNA_PIN ((CONFIG_BT_CTLR_GPIO_LNA_PIN) - 32) -#else -#define NRF_GPIO_LNA NRF_P0 -#define NRF_GPIO_LNA_PIN CONFIG_BT_CTLR_GPIO_LNA_PIN -#endif +#define NRF_GPIO_LNA NRF_FEM_GPIO(HAL_RADIO_GPIO_LNA_PROP) +#define NRF_GPIO_LNA_PIN DT_GPIO_PIN(FEM_NODE, HAL_RADIO_GPIO_LNA_PROP) +#define NRF_GPIO_LNA_FLAGS DT_GPIO_FLAGS(FEM_NODE, HAL_RADIO_GPIO_LNA_PROP) +#define NRF_GPIO_LNA_PSEL NRF_FEM_PSEL(HAL_RADIO_GPIO_LNA_PROP) +NRF_DT_CHECK_GPIO_CTLR_IS_SOC(FEM_NODE, HAL_RADIO_GPIO_LNA_PROP, + HAL_RADIO_GPIO_LNA_PROP_NAME); +BUILD_ASSERT(!BAD_FLAGS(NRF_GPIO_LNA_FLAGS), + "fem node " DT_NODE_PATH(FEM_NODE) " has invalid GPIO flags in " + HAL_RADIO_GPIO_LNA_PROP_NAME + "; only GPIO_ACTIVE_LOW or GPIO_ACTIVE_HIGH are supported"); #endif /* HAL_RADIO_GPIO_HAVE_LNA_PIN */ -#if defined(CONFIG_BT_CTLR_GPIO_PDN_PIN) -#if ((CONFIG_BT_CTLR_GPIO_PDN_PIN) > 31) -#define NRF_GPIO_PDN NRF_P1 -#define NRF_GPIO_PDN_PIN ((CONFIG_BT_CTLR_GPIO_PDN_PIN) - 32) -#else -#define NRF_GPIO_PDN NRF_P0 -#define NRF_GPIO_PDN_PIN CONFIG_BT_CTLR_GPIO_PDN_PIN -#endif -#endif /* CONFIG_BT_CTLR_GPIO_PDN_PIN */ +#if defined(HAL_RADIO_FEM_IS_NRF21540) -#if defined(CONFIG_BT_CTLR_GPIO_CSN_PIN) -#if ((CONFIG_BT_CTLR_GPIO_CSN_PIN) > 31) -#define NRF_GPIO_CSN NRF_P1 -#define NRF_GPIO_CSN_PIN ((CONFIG_BT_CTLR_GPIO_CSN_PIN) - 32) -#else -#define NRF_GPIO_CSN NRF_P0 -#define NRF_GPIO_CSN_PIN CONFIG_BT_CTLR_GPIO_CSN_PIN -#endif -#endif /* CONFIG_BT_CTLR_GPIO_CSN_PIN */ +#if DT_NODE_HAS_PROP(FEM_NODE, pdn_gpios) +#define NRF_GPIO_PDN NRF_FEM_GPIO(pdn_gpios) +#define NRF_GPIO_PDN_PIN DT_GPIO_PIN(FEM_NODE, pdn_gpios) +#define NRF_GPIO_PDN_FLAGS DT_GPIO_FLAGS(FEM_NODE, pdn_gpios) +#define NRF_GPIO_PDN_PSEL NRF_FEM_PSEL(pdn_gpios) +#define NRF_GPIO_PDN_OFFSET DT_PROP(FEM_NODE, pdn_settle_time_us) +NRF_DT_CHECK_GPIO_CTLR_IS_SOC(FEM_NODE, pdn_gpios, "pdn-gpios"); +#endif /* DT_NODE_HAS_PROP(FEM_NODE, pdn_gpios) */ +/* CSN is special because it comes from the spi-if property. */ +#if defined(HAL_RADIO_FEM_NRF21540_HAS_CSN) +#define NRF_GPIO_CSN_CTLR DT_SPI_DEV_CS_GPIOS_CTLR(FEM_SPI_DEV_NODE) +#define NRF_GPIO_CSN ((NRF_GPIO_Type *)DT_REG_ADDR(NRF_GPIO_CSN_CTLR)) +#define NRF_GPIO_CSN_PIN DT_SPI_DEV_CS_GPIOS_PIN(FEM_SPI_DEV_NODE) +#define NRF_GPIO_CSN_FLAGS DT_SPI_DEV_CS_GPIOS_FLAGS(FEM_SPI_DEV_NODE) +#define NRF_GPIO_CSN_PSEL (NRF_GPIO_CSN_PIN + \ + (DT_PROP(NRF_GPIO_CSN_CTLR, port) << 5)) +BUILD_ASSERT(DT_NODE_HAS_COMPAT(NRF_GPIO_CSN_CTLR, nordic_nrf_gpio), + "fem node " DT_NODE_PATH(FEM_NODE) " has a spi-if property, " + " but the chip select pin is not on the SoC. Check cs-gpios in " + DT_NODE_PATH(DT_BUS(FEM_SPI_DEV_NODE))); +#endif /* HAL_RADIO_FEM_NRF21540_HAS_CSN */ + +#endif /* HAL_RADIO_FEM_IS_NRF21540 */ /* The following two constants are used in nrfx_glue.h for marking these PPI * channels and groups as occupied and thus unavailable to other modules. @@ -107,11 +165,11 @@ void radio_setup(void) { #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) NRF_GPIO_PA->DIRSET = BIT(NRF_GPIO_PA_PIN); -#if defined(HAL_RADIO_GPIO_PA_POL_INV) - NRF_GPIO_PA->OUTSET = BIT(NRF_GPIO_PA_PIN); -#else - NRF_GPIO_PA->OUTCLR = BIT(NRF_GPIO_PA_PIN); -#endif + if (ACTIVE_LOW(NRF_GPIO_PA_FLAGS)) { + NRF_GPIO_PA->OUTSET = BIT(NRF_GPIO_PA_PIN); + } else { + NRF_GPIO_PA->OUTCLR = BIT(NRF_GPIO_PA_PIN); + } #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */ #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN) @@ -120,23 +178,23 @@ void radio_setup(void) radio_gpio_lna_off(); #endif /* HAL_RADIO_GPIO_HAVE_LNA_PIN */ -#if defined(CONFIG_BT_CTLR_GPIO_PDN_PIN) +#if defined(NRF_GPIO_PDN_PIN) NRF_GPIO_PDN->DIRSET = BIT(NRF_GPIO_PDN_PIN); -#if defined(HAL_RADIO_GPIO_NRF21540_PDN_POL_INV) - NRF_GPIO_PDN->OUTSET = BIT(NRF_GPIO_PDN_PIN); -#else - NRF_GPIO_PDN->OUTCLR = BIT(NRF_GPIO_PDN_PIN); -#endif -#endif /* CONFIG_BT_CTLR_GPIO_PDN_PIN */ + if (ACTIVE_LOW(NRF_GPIO_PDN_FLAGS)) { + NRF_GPIO_PDN->OUTSET = BIT(NRF_GPIO_PDN_PIN); + } else { + NRF_GPIO_PDN->OUTCLR = BIT(NRF_GPIO_PDN_PIN); + } +#endif /* NRF_GPIO_PDN_PIN */ -#if defined(CONFIG_BT_CTLR_GPIO_CSN_PIN) +#if defined(NRF_GPIO_CSN_PIN) NRF_GPIO_CSN->DIRSET = BIT(NRF_GPIO_CSN_PIN); -#if defined(HAL_RADIO_GPIO_NRF21540_CSN_POL_INV) - NRF_GPIO_CSN->OUTSET = BIT(NRF_GPIO_CSN_PIN); -#else - NRF_GPIO_CSN->OUTCLR = BIT(NRF_GPIO_CSN_PIN); -#endif -#endif /* CONFIG_BT_CTLR_GPIO_CSN_PIN */ + if (ACTIVE_LOW(NRF_GPIO_CSN_FLAGS)) { + NRF_GPIO_CSN->OUTSET = BIT(NRF_GPIO_CSN_PIN); + } else { + NRF_GPIO_CSN->OUTCLR = BIT(NRF_GPIO_CSN_PIN); + } +#endif /* NRF_GPIO_CSN_PIN */ hal_radio_ram_prio_setup(); } @@ -1125,24 +1183,15 @@ uint32_t radio_tmr_sample_get(void) #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) void radio_gpio_pa_setup(void) { - /* NOTE: With GPIO Pins above 31, left shift of - * CONFIG_BT_CTLR_GPIO_PA_PIN by GPIOTE_CONFIG_PSEL_Pos will - * set the NRF_GPIOTE->CONFIG[n].PORT to 1 (P1 port). - */ NRF_GPIOTE->CONFIG[HAL_PALNA_GPIOTE_CHAN] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | - (CONFIG_BT_CTLR_GPIO_PA_PIN << + (NRF_GPIO_PA_PSEL << GPIOTE_CONFIG_PSEL_Pos) | (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) | -#if defined(HAL_RADIO_GPIO_PA_POL_INV) - (GPIOTE_CONFIG_OUTINIT_High << + (OUTINIT_INACTIVE(NRF_GPIO_PA_FLAGS) << GPIOTE_CONFIG_OUTINIT_Pos); -#else - (GPIOTE_CONFIG_OUTINIT_Low << - GPIOTE_CONFIG_OUTINIT_Pos); -#endif #if defined(HAL_RADIO_FEM_IS_NRF21540) hal_pa_ppi_setup(); @@ -1155,24 +1204,15 @@ void radio_gpio_pa_setup(void) #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN) void radio_gpio_lna_setup(void) { - /* NOTE: With GPIO Pins above 31, left shift of - * CONFIG_BT_CTLR_GPIO_LNA_PIN by GPIOTE_CONFIG_PSEL_Pos will - * set the NRF_GPIOTE->CONFIG[n].PORT to 1 (P1 port). - */ NRF_GPIOTE->CONFIG[HAL_PALNA_GPIOTE_CHAN] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | - (CONFIG_BT_CTLR_GPIO_LNA_PIN << + (NRF_GPIO_LNA_PSEL << GPIOTE_CONFIG_PSEL_Pos) | (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) | -#if defined(HAL_RADIO_GPIO_LNA_POL_INV) - (GPIOTE_CONFIG_OUTINIT_High << + (OUTINIT_INACTIVE(NRF_GPIO_LNA_FLAGS) << GPIOTE_CONFIG_OUTINIT_Pos); -#else - (GPIOTE_CONFIG_OUTINIT_Low << - GPIOTE_CONFIG_OUTINIT_Pos); -#endif #if defined(HAL_RADIO_FEM_IS_NRF21540) hal_lna_ppi_setup(); @@ -1181,79 +1221,62 @@ void radio_gpio_lna_setup(void) #endif } -#if defined(CONFIG_BT_CTLR_GPIO_PDN_PIN) void radio_gpio_pdn_setup(void) { - /* NOTE: With GPIO Pins above 31, left shift of - * CONFIG_BT_CTLR_GPIO_PA_PIN by GPIOTE_CONFIG_PSEL_Pos will - * set the NRF_GPIOTE->CONFIG[n].PORT to 1 (P1 port). - */ + /* Note: the pdn-gpios property is optional. */ +#if defined(NRF_GPIO_PDN) NRF_GPIOTE->CONFIG[HAL_PDN_GPIOTE_CHAN] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | - (CONFIG_BT_CTLR_GPIO_PDN_PIN << + (NRF_GPIO_PDN_PSEL << GPIOTE_CONFIG_PSEL_Pos) | (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) | -#if defined(HAL_RADIO_GPIO_NRF21540_PDN_POL_INV) - (GPIOTE_CONFIG_OUTINIT_High << + (OUTINIT_INACTIVE(NRF_GPIO_PDN_FLAGS) << GPIOTE_CONFIG_OUTINIT_Pos); -#else - (GPIOTE_CONFIG_OUTINIT_Low << - GPIOTE_CONFIG_OUTINIT_Pos); -#endif +#endif /* NRF_GPIO_PDN_PIN */ } -#endif /* CONFIG_BT_CTLR_GPIO_PDN_PIN */ -#if defined(CONFIG_BT_CTLR_GPIO_CSN_PIN) void radio_gpio_csn_setup(void) { - /* NOTE: With GPIO Pins above 31, left shift of - * CONFIG_BT_CTLR_GPIO_PA_PIN by GPIOTE_CONFIG_PSEL_Pos will - * set the NRF_GPIOTE->CONFIG[n].PORT to 1 (P1 port). - */ + /* Note: the spi-if property is optional. */ +#if defined(NRF_GPIO_CSN_PIN) NRF_GPIOTE->CONFIG[HAL_CSN_GPIOTE_CHAN] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | - (CONFIG_BT_CTLR_GPIO_CSN_PIN << + (NRF_GPIO_CSN_PSEL << GPIOTE_CONFIG_PSEL_Pos) | (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) | -#if defined(HAL_RADIO_GPIO_NRF21540_CSN_POL_INV) - (GPIOTE_CONFIG_OUTINIT_High << + (OUTINIT_INACTIVE(NRF_GPIO_CSN_FLAGS) << GPIOTE_CONFIG_OUTINIT_Pos); -#else - (GPIOTE_CONFIG_OUTINIT_Low << - GPIOTE_CONFIG_OUTINIT_Pos); -#endif +#endif /* NRF_GPIO_CSN_PIN */ } -#endif /* CONFIG_BT_CTLR_GPIO_CSN_PIN */ void radio_gpio_lna_on(void) { -#if defined(HAL_RADIO_GPIO_LNA_POL_INV) - NRF_GPIO_LNA->OUTCLR = BIT(NRF_GPIO_LNA_PIN); -#else - NRF_GPIO_LNA->OUTSET = BIT(NRF_GPIO_LNA_PIN); -#endif + if (ACTIVE_LOW(NRF_GPIO_LNA_FLAGS)) { + NRF_GPIO_LNA->OUTCLR = BIT(NRF_GPIO_LNA_PIN); + } else { + NRF_GPIO_LNA->OUTSET = BIT(NRF_GPIO_LNA_PIN); + } } void radio_gpio_lna_off(void) { -#if defined(HAL_RADIO_GPIO_LNA_POL_INV) - NRF_GPIO_LNA->OUTSET = BIT(NRF_GPIO_LNA_PIN); -#else - NRF_GPIO_LNA->OUTCLR = BIT(NRF_GPIO_LNA_PIN); -#endif + if (ACTIVE_LOW(NRF_GPIO_LNA_FLAGS)) { + NRF_GPIO_LNA->OUTSET = BIT(NRF_GPIO_LNA_PIN); + } else { + NRF_GPIO_LNA->OUTCLR = BIT(NRF_GPIO_LNA_PIN); + } } #endif /* HAL_RADIO_GPIO_HAVE_LNA_PIN */ void radio_gpio_pa_lna_enable(uint32_t trx_us) { nrf_timer_cc_set(EVENT_TIMER, 2, trx_us); -#if defined(HAL_RADIO_FEM_IS_NRF21540) - nrf_timer_cc_set(EVENT_TIMER, 3, (trx_us - - HAL_RADIO_GPIO_NRF21540_PDN_OFFSET)); +#if defined(HAL_RADIO_FEM_IS_NRF21540) && DT_NODE_HAS_PROP(FEM_NODE, pdn_gpios) + nrf_timer_cc_set(EVENT_TIMER, 3, (trx_us - NRF_GPIO_PDN_OFFSET)); hal_radio_nrf_ppi_channels_enable(BIT(HAL_ENABLE_PALNA_PPI) | BIT(HAL_DISABLE_PALNA_PPI) | BIT(HAL_ENABLE_FEM_PPI) | diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h index 7ff85525838..46fc2a5c981 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h @@ -60,39 +60,8 @@ #define HAL_CSN_GPIOTE_CHAN 2 #endif -#if defined(CONFIG_BT_CTLR_GPIO_PA) -#define HAL_RADIO_GPIO_HAVE_PA_PIN 1 -#endif -#if defined(CONFIG_BT_CTLR_GPIO_LNA) -#define HAL_RADIO_GPIO_HAVE_LNA_PIN 1 -#endif - -#if defined(CONFIG_BT_CTLR_GPIO_PA_POL_INV) -#define HAL_RADIO_GPIO_PA_POL_INV CONFIG_BT_CTLR_GPIO_PA_POL_INV -#endif -#if defined(CONFIG_BT_CTLR_GPIO_LNA_POL_INV) -#define HAL_RADIO_GPIO_LNA_POL_INV CONFIG_BT_CTLR_GPIO_LNA_POL_INV -#endif -#if defined(CONFIG_BT_CTLR_GPIO_PDN_POL_INV) -#define HAL_RADIO_GPIO_NRF21540_PDN_POL_INV CONFIG_BT_CTLR_GPIO_PDN_POL_INV -#endif -#if defined(CONFIG_BT_CTLR_GPIO_CSN_POL_INV) -#define HAL_RADIO_GPIO_NRF21540_CSN_POL_INV CONFIG_BT_CTLR_GPIO_CSN_POL_INV -#endif - -#if defined(CONFIG_BT_CTLR_GPIO_PA_OFFSET) -#define HAL_RADIO_GPIO_PA_OFFSET CONFIG_BT_CTLR_GPIO_PA_OFFSET -#endif -#if defined(CONFIG_BT_CTLR_GPIO_LNA_OFFSET) -#define HAL_RADIO_GPIO_LNA_OFFSET CONFIG_BT_CTLR_GPIO_LNA_OFFSET -#endif -#if defined(CONFIG_BT_CTLR_GPIO_PDN_CSN_OFFSET) -#define HAL_RADIO_GPIO_NRF21540_PDN_OFFSET CONFIG_BT_CTLR_GPIO_PDN_CSN_OFFSET -#endif - -#if defined(CONFIG_BT_CTLR_FEM_NRF21540) -#define HAL_RADIO_FEM_IS_NRF21540 1 -#endif +/* This has to come before the ppi/dppi includes below. */ +#include "radio_nrf5_fem.h" #if defined(PPI_PRESENT) #include "radio_nrf5_ppi.h" diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_fem.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_fem.h new file mode 100644 index 00000000000..7d419c1b374 --- /dev/null +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_fem.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Generic helper macros for getting radio front-end module (FEM) + * settings from devicetree. The main task here is to check the + * devicetree compatible of the node the fem property points at, and + * pull in a subheader that translates from that compatible's specific + * properties to the generic macros required by the nRF5 radio HAL. + */ + +#include +#include + +#if DT_NODE_HAS_PROP(DT_NODELABEL(radio), fem) +#define FEM_NODE DT_PHANDLE(DT_NODELABEL(radio), fem) +#if DT_NODE_HAS_STATUS(FEM_NODE, okay) +#define HAL_RADIO_HAVE_FEM +#endif /* DT_NODE_HAS_STATUS(FEM_NODE, okay) */ +#endif /* DT_NODE_HAS_PROP(DT_NODELABEL(radio), fem)) */ + +/* Does FEM_NODE have a particular DT compatible? */ +#define FEM_HAS_COMPAT(compat) DT_NODE_HAS_COMPAT(FEM_NODE, compat) + +/* Does FEM_NODE have a particular DT property defined? */ +#define FEM_HAS_PROP(prop) DT_NODE_HAS_PROP(FEM_NODE, prop) + +/* + * Device-specific settings are pulled in based FEM_NODE's compatible + * property. + */ + +#ifdef HAL_RADIO_HAVE_FEM +#if FEM_HAS_COMPAT(generic_fem_two_ctrl_pins) +#include "radio_nrf5_fem_generic.h" +#elif FEM_HAS_COMPAT(nordic_nrf21540_fem) +#include "radio_nrf5_fem_nrf21540.h" +#else +#error "radio node fem property has an unsupported compatible" +#endif /* FEM_HAS_COMPAT(generic_fem_two_ctrl_pins) */ +#endif /* HAL_RADIO_HAVE_FEM */ + +/* + * Define POL_INV macros expected by radio_nrf5_dppi as needed. + */ + +#ifdef HAL_RADIO_GPIO_HAVE_PA_PIN +#if DT_GPIO_FLAGS(FEM_NODE, HAL_RADIO_GPIO_PA_PROP) & GPIO_ACTIVE_LOW +#define HAL_RADIO_GPIO_PA_POL_INV +#endif +#endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */ + +#ifdef HAL_RADIO_GPIO_HAVE_LNA_PIN +#if DT_GPIO_FLAGS(FEM_NODE, HAL_RADIO_GPIO_LNA_PROP) & GPIO_ACTIVE_LOW +#define HAL_RADIO_GPIO_LNA_POL_INV +#endif +#endif /* HAL_RADIO_GPIO_HAVE_LNA_PIN */ diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_fem_generic.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_fem_generic.h new file mode 100644 index 00000000000..f99a73991c9 --- /dev/null +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_fem_generic.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * This file contains helper macros for dealing with the devicetree + * radio node's fem property, in the case that it has compatible + * "generic-fem-two-ctrl-pins". + * + * Do not include it directly. + * + * For these devices: + * + * Value Property + * --------- -------- + * PA pin ctx-gpios + * PA offset ctx-settle-time-us + * LNA pin crx-gpios + * LNA offset crx-settle-time-us + */ + +#define HAL_RADIO_GPIO_PA_PROP_NAME "ctx-gpios" +#define HAL_RADIO_GPIO_PA_OFFSET_PROP_NAME "ctx-settle-time-us" +#define HAL_RADIO_GPIO_LNA_PROP_NAME "crx-gpios" +#define HAL_RADIO_GPIO_LNA_OFFSET_PROP_NAME "crx-settle-time-us" + +#if FEM_HAS_PROP(ctx_gpios) +#define HAL_RADIO_GPIO_HAVE_PA_PIN 1 +#define HAL_RADIO_GPIO_PA_PROP ctx_gpios + +#define HAL_RADIO_GPIO_PA_OFFSET_MISSING (!FEM_HAS_PROP(ctx_settle_time_us)) +#define HAL_RADIO_GPIO_PA_OFFSET \ + DT_PROP_OR(FEM_NODE, ctx_settle_time_us, 0) +#else /* !FEM_HAS_PROP(ctx_gpios) */ +#define HAL_RADIO_GPIO_PA_OFFSET_MISSING 0 +#endif /* FEM_HAS_PROP(ctx_gpios) */ + +#if FEM_HAS_PROP(crx_gpios) +#define HAL_RADIO_GPIO_HAVE_LNA_PIN 1 +#define HAL_RADIO_GPIO_LNA_PROP crx_gpios + +#define HAL_RADIO_GPIO_LNA_OFFSET_MISSING (!FEM_HAS_PROP(crx_settle_time_us)) +#define HAL_RADIO_GPIO_LNA_OFFSET \ + DT_PROP_OR(FEM_NODE, crx_settle_time_us, 0) +#else /* !FEM_HAS_PROP(crx_gpios) */ +#define HAL_RADIO_GPIO_LNA_OFFSET_MISSING 0 +#endif /* FEM_HAS_PROP(crx_gpios) */ diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_fem_nrf21540.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_fem_nrf21540.h new file mode 100644 index 00000000000..6b473198ffa --- /dev/null +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_fem_nrf21540.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * This file contains helper macros for dealing with the devicetree + * radio node's fem property, in the case that it has compatible + * "nordic,nrf21540-fem". + * + * Do not include it directly. + * + * For nRF21540 devices: + * + * Value Property + * --------- -------- + * PA pin tx-en-gpios + * PA offset tx-en-settle-time-us + * LNA pin rx-en-gpios + * LNA offset rx-en-settle-time-us + * PDN pin pdn-gpios + * PDN offset pdn-settle-time-us + * + * The spi-if property may point at a SPI device node representing the + * FEM's SPI control interface. See the binding for details. + */ + +#define HAL_RADIO_FEM_IS_NRF21540 1 + +#define HAL_RADIO_GPIO_PA_PROP_NAME "tx-en-gpios" +#define HAL_RADIO_GPIO_PA_OFFSET_PROP_NAME "tx-en-settle-time-us" +#define HAL_RADIO_GPIO_LNA_PROP_NAME "rx-en-gpios" +#define HAL_RADIO_GPIO_LNA_OFFSET_PROP_NAME "rx-en-settle-time-us" + +/* This FEM's PA and LNA offset properties have defaults set. */ +#define HAL_RADIO_GPIO_PA_OFFSET_MISSING 0 +#define HAL_RADIO_GPIO_LNA_OFFSET_MISSING 0 + +#if FEM_HAS_PROP(tx_en_gpios) +#define HAL_RADIO_GPIO_HAVE_PA_PIN 1 +#define HAL_RADIO_GPIO_PA_PROP tx_en_gpios +#define HAL_RADIO_GPIO_PA_OFFSET DT_PROP(FEM_NODE, tx_en_settle_time_us) +#endif /* FEM_HAS_PROP(tx_en_gpios) */ + +#if FEM_HAS_PROP(rx_en_gpios) +#define HAL_RADIO_GPIO_HAVE_LNA_PIN 1 +#define HAL_RADIO_GPIO_LNA_PROP rx_en_gpios +#define HAL_RADIO_GPIO_LNA_OFFSET DT_PROP(FEM_NODE, rx_en_settle_time_us) +#endif /* FEM_HAS_PROP(rx_en_gpios) */ + +/* + * The POL_INV macros defined below are just to keep things simple in + * radio_nrf5_dppi.h, which uses them. + */ + +#if FEM_HAS_PROP(pdn_gpios) +#if DT_GPIO_FLAGS(FEM_NODE, pdn_gpios) & GPIO_ACTIVE_LOW +#define HAL_RADIO_GPIO_NRF21540_PDN_POL_INV 1 +#endif /* DT_GPIO_FLAGS(FEM_NODE, pdn_gpios) & GPIO_ACTIVE_LOW */ +#endif /* FEM_HAS_PROP(pdn_gpios) */ + +#if FEM_HAS_PROP(spi_if) +/* This is the "SPI device" node, i.e. the one with compatible + * nordic,nrf21540-fem-spi. + */ +#define FEM_SPI_DEV_NODE DT_PHANDLE(FEM_NODE, spi_if) +/* If the SPI device node has a chip select gpio... */ +#if DT_SPI_DEV_HAS_CS_GPIOS(FEM_SPI_DEV_NODE) +/* set a macro indicating that, and... */ +#define HAL_RADIO_FEM_NRF21540_HAS_CSN 1 +/* use it to get the CSN polarity. */ +#if DT_SPI_DEV_CS_GPIOS_FLAGS(FEM_SPI_DEV_NODE) & GPIO_ACTIVE_LOW +#define HAL_RADIO_GPIO_NRF21540_CSN_POL_INV 1 +#endif /* DT_SPI_DEV_CS_GPIOS_FLAGS(FEM_SPI_DEV_NODE) & GPIO_ACTIVE_LOW */ +#endif /* DT_SPI_DEV_HAS_CS_GPIOS(FEM_SPI_DEV_NODE) */ +#endif /* FEM_HAS_PROP(spi_if) */ diff --git a/subsys/bluetooth/controller/ll_sw/openisa/hal/radio_vendor_hal.h b/subsys/bluetooth/controller/ll_sw/openisa/hal/radio_vendor_hal.h index 267b9c3f7f0..a90aca8fd7b 100644 --- a/subsys/bluetooth/controller/ll_sw/openisa/hal/radio_vendor_hal.h +++ b/subsys/bluetooth/controller/ll_sw/openisa/hal/radio_vendor_hal.h @@ -6,16 +6,11 @@ #include "hal/RV32M1/radio/radio.h" -#if defined(CONFIG_BT_CTLR_GPIO_PA) -#define HAL_RADIO_GPIO_HAVE_PA_PIN -#endif -#if defined(CONFIG_BT_CTLR_GPIO_LNA) -#define HAL_RADIO_GPIO_HAVE_LNA_PIN -#endif - -#if defined(CONFIG_BT_CTLR_GPIO_PA_OFFSET) -#define HAL_RADIO_GPIO_PA_OFFSET CONFIG_BT_CTLR_GPIO_PA_OFFSET -#endif -#if defined(CONFIG_BT_CTLR_GPIO_LNA_OFFSET) -#define HAL_RADIO_GPIO_LNA_OFFSET CONFIG_BT_CTLR_GPIO_LNA_OFFSET -#endif +/* The openisa vendor HAL does not have the GPIO support functions + * required for handling radio front-end modules with PA/LNAs. + * + * If these are ever implemented, this file should be updated + * appropriately. + */ +#undef HAL_RADIO_GPIO_HAVE_PA_PIN +#undef HAL_RADIO_GPIO_HAVE_LNA_PIN diff --git a/tests/bluetooth/init/pa_lna.overlay b/tests/bluetooth/init/pa_lna.overlay new file mode 100644 index 00000000000..5ff670b76e8 --- /dev/null +++ b/tests/bluetooth/init/pa_lna.overlay @@ -0,0 +1,13 @@ +/ { + nrf_radio_fem: fem { + compatible = "generic-fem-two-ctrl-pins"; + ctx-gpios = <&gpio0 26 0>; + ctx-settle-time-us = <5>; + crx-gpios = <&gpio0 27 0>; + crx-settle-time-us = <5>; + }; +}; + +&radio { + fem = <&nrf_radio_fem>; +}; diff --git a/tests/bluetooth/init/prj_ctlr_4_0.conf b/tests/bluetooth/init/prj_ctlr_4_0.conf index 016e460e916..3141484dc99 100644 --- a/tests/bluetooth/init/prj_ctlr_4_0.conf +++ b/tests/bluetooth/init/prj_ctlr_4_0.conf @@ -24,8 +24,6 @@ CONFIG_BT_CTLR_CONN_RSSI=n CONFIG_BT_CTLR_ADV_INDICATION=n CONFIG_BT_CTLR_SCAN_REQ_NOTIFY=n CONFIG_BT_CTLR_SCAN_REQ_RSSI=n -CONFIG_BT_CTLR_GPIO_PA=n -CONFIG_BT_CTLR_GPIO_LNA=n CONFIG_BT_CTLR_PROFILE_ISR=n CONFIG_BT_CTLR_DEBUG_PINS=n CONFIG_BT_HCI_VS_EXT=n diff --git a/tests/bluetooth/init/prj_ctlr_4_0_dbg.conf b/tests/bluetooth/init/prj_ctlr_4_0_dbg.conf index 4e3ad65afad..549abd02f23 100644 --- a/tests/bluetooth/init/prj_ctlr_4_0_dbg.conf +++ b/tests/bluetooth/init/prj_ctlr_4_0_dbg.conf @@ -26,8 +26,6 @@ CONFIG_BT_CTLR_CONN_RSSI=n CONFIG_BT_CTLR_ADV_INDICATION=n CONFIG_BT_CTLR_SCAN_REQ_NOTIFY=n CONFIG_BT_CTLR_SCAN_REQ_RSSI=n -CONFIG_BT_CTLR_GPIO_PA=n -CONFIG_BT_CTLR_GPIO_LNA=n CONFIG_BT_CTLR_PROFILE_ISR=n CONFIG_BT_CTLR_DEBUG_PINS=n CONFIG_BT_HCI_VS_EXT=n diff --git a/tests/bluetooth/init/prj_ctlr_dbg.conf b/tests/bluetooth/init/prj_ctlr_dbg.conf index a3e1db67aa0..7eb09931813 100644 --- a/tests/bluetooth/init/prj_ctlr_dbg.conf +++ b/tests/bluetooth/init/prj_ctlr_dbg.conf @@ -30,10 +30,6 @@ CONFIG_BT_CTLR_ADV_INDICATION=y CONFIG_BT_CTLR_SCAN_REQ_NOTIFY=y CONFIG_BT_CTLR_SCAN_REQ_RSSI=y CONFIG_BT_CTLR_SCAN_INDICATION=y -CONFIG_BT_CTLR_GPIO_PA=y -CONFIG_BT_CTLR_GPIO_PA_PIN=26 -CONFIG_BT_CTLR_GPIO_LNA=y -CONFIG_BT_CTLR_GPIO_LNA_PIN=27 CONFIG_BT_CTLR_PROFILE_ISR=y CONFIG_BT_CTLR_DEBUG_PINS=y CONFIG_BT_CTLR_TEST=y diff --git a/tests/bluetooth/init/prj_ctlr_tiny.conf b/tests/bluetooth/init/prj_ctlr_tiny.conf index 6dc864f1351..949f5b5fac7 100644 --- a/tests/bluetooth/init/prj_ctlr_tiny.conf +++ b/tests/bluetooth/init/prj_ctlr_tiny.conf @@ -28,8 +28,6 @@ CONFIG_BT_CTLR_ADV_INDICATION=n CONFIG_BT_CTLR_SCAN_REQ_NOTIFY=n CONFIG_BT_CTLR_SCAN_REQ_RSSI=n CONFIG_BT_CTLR_PROFILE_ISR=n -CONFIG_BT_CTLR_GPIO_PA=n -CONFIG_BT_CTLR_GPIO_LNA=n CONFIG_BT_CTLR_PROFILE_ISR=n CONFIG_BT_CTLR_DEBUG_PINS=n CONFIG_BT_HCI_VS_EXT=n diff --git a/tests/bluetooth/init/testcase.yaml b/tests/bluetooth/init/testcase.yaml index 7840b4832df..e4ee1b085eb 100644 --- a/tests/bluetooth/init/testcase.yaml +++ b/tests/bluetooth/init/testcase.yaml @@ -104,7 +104,7 @@ tests: - nrf52dk_nrf52832 - nrf51dk_nrf51422 bluetooth.init.test_ctlr_dbg: - extra_args: CONF_FILE=prj_ctlr_dbg.conf + extra_args: CONF_FILE=prj_ctlr_dbg.conf DTC_OVERLAY_FILE=pa_lna.overlay platform_allow: nrf52840dk_nrf52840 nrf52dk_nrf52832 nrf51dk_nrf51422 integration_platforms: