Commit e9256135 authored by Andrzej Głąbek's avatar Andrzej Głąbek Committed by Anas Nashif
Browse files

Bluetooth: Controller: nrf5: Allocate GPIOTE channels



Allocate the GPIOTE channels that the Bluetooth Controller needs to use
with the dedicated function provided by the nrfx_gpiote driver instead
of using hard-coded indexes of these channels, as now, when the driver
supports multiple GPIOTE instances, it would be much more difficult to
properly inform the driver which channels should be reserved.

Signed-off-by: default avatarAndrzej Głąbek <andrzej.glabek@nordicsemi.no>
parent 2e8f1044
Loading
Loading
Loading
Loading
+0 −19
Original line number Diff line number Diff line
@@ -18,25 +18,6 @@
#include "../radio/radio_nrf5_ppi_resources.h"
#endif

#if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || \
	defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
#define HAL_PALNA_GPIOTE_CHAN 0
#define HAL_PALNA_GPIOTE_MASK BIT(HAL_PALNA_GPIOTE_CHAN)
#else
#define HAL_PALNA_GPIOTE_MASK 0
#endif

#if defined(HAL_RADIO_FEM_IS_NRF21540)
#define HAL_PDN_GPIOTE_CHAN 1
#define HAL_CSN_GPIOTE_CHAN 2
#define HAL_PDN_CSN_GPIOTE_MASK (BIT(HAL_PDN_GPIOTE_CHAN) | BIT(HAL_CSN_GPIOTE_CHAN))
#else
#define HAL_PDN_CSN_GPIOTE_MASK 0
#endif

/* Mask with all GPIOTE channels used by the bluetooth controller. */
#define BT_CTLR_USED_GPIOTE_CHANNELS (HAL_PALNA_GPIOTE_MASK | HAL_PDN_CSN_GPIOTE_MASK)

/* Mask with all (D)PPI channels used by the bluetooth controller. */
#define BT_CTLR_USED_PPI_CHANNELS \
	(BIT(HAL_RADIO_ENABLE_TX_ON_TICK_PPI) | \
+74 −8
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <hal/nrf_radio.h>
#include <hal/nrf_ccm.h>
#include <hal/nrf_aar.h>
#include <nrfx_gpiote.h>

#include "util/mem.h"

@@ -67,6 +68,33 @@ BUILD_ASSERT(!HAL_RADIO_GPIO_LNA_OFFSET_MISSING,
	     HAL_RADIO_GPIO_LNA_OFFSET_PROP_NAME);
#endif	/* FEM_NODE */

#if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
static const nrfx_gpiote_t gpiote_palna = NRFX_GPIOTE_INSTANCE(
	NRF_DT_GPIOTE_INST(FEM_NODE, HAL_RADIO_GPIO_PA_PROP));
static uint8_t gpiote_ch_palna;

BUILD_ASSERT(NRF_DT_GPIOTE_INST(FEM_NODE, HAL_RADIO_GPIO_PA_PROP) ==
	     NRF_DT_GPIOTE_INST(FEM_NODE, HAL_RADIO_GPIO_LNA_PROP),
	HAL_RADIO_GPIO_PA_PROP_NAME " and " HAL_RADIO_GPIO_LNA_PROP_NAME
	" GPIOs must use the same GPIOTE instance.");
#endif

#if defined(HAL_RADIO_FEM_IS_NRF21540)
static const nrfx_gpiote_t gpiote_pdn = NRFX_GPIOTE_INSTANCE(
	NRF_DT_GPIOTE_INST(FEM_NODE, pdn_gpios));
static uint8_t gpiote_ch_pdn;
static const nrfx_gpiote_t gpiote_csn = NRFX_GPIOTE_INSTANCE(
	NRF_DT_GPIOTE_INST(DT_BUS(FEM_SPI_DEV_NODE), cs_gpios));
static uint8_t gpiote_ch_csn;
#endif

/* These headers require the above gpiote-related variables to be declared. */
#if defined(PPI_PRESENT)
#include "radio_nrf5_ppi_gpiote.h"
#elif defined(DPPI_PRESENT)
#include "radio_nrf5_dppi_gpiote.h"
#endif

/*
 * "Manual" conversions of devicetree values to register bits. We
 * can't use the Zephyr GPIO API here, so we need this extra
@@ -1548,10 +1576,48 @@ uint32_t radio_tmr_sample_get(void)

#if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || \
	defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
int radio_gpio_pa_lna_init(void)
{
#if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
	if (nrfx_gpiote_channel_alloc(&gpiote_palna, &gpiote_ch_palna) != NRFX_SUCCESS) {
		return -ENOMEM;
	}
#endif

#if defined(NRF_GPIO_PDN_PIN)
	if (nrfx_gpiote_channel_alloc(&gpiote_pdn, &gpiote_ch_pdn) != NRFX_SUCCESS) {
		return -ENOMEM;
	}
#endif

#if defined(NRF_GPIO_CSN_PIN)
	if (nrfx_gpiote_channel_alloc(&gpiote_csn, &gpiote_ch_csn) != NRFX_SUCCESS) {
		return -ENOMEM;
	}
#endif

	return 0;
}

void radio_gpio_pa_lna_deinit(void)
{
#if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
	(void)nrfx_gpiote_channel_free(&gpiote_palna, gpiote_ch_palna);
#endif

#if defined(NRF_GPIO_PDN_PIN)
	(void)nrfx_gpiote_channel_free(&gpiote_pdn, gpiote_ch_pdn);
#endif

#if defined(NRF_GPIO_CSN_PIN)
	(void)nrfx_gpiote_channel_free(&gpiote_csn, gpiote_ch_csn);
#endif
}

#if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
void radio_gpio_pa_setup(void)
{
	NRF_GPIOTE->CONFIG[HAL_PALNA_GPIOTE_CHAN] =
	gpiote_palna.p_reg->CONFIG[gpiote_ch_palna] =
		(GPIOTE_CONFIG_MODE_Task <<
		 GPIOTE_CONFIG_MODE_Pos) |
		(NRF_GPIO_PA_PSEL <<
@@ -1572,7 +1638,7 @@ void radio_gpio_pa_setup(void)
#if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
void radio_gpio_lna_setup(void)
{
	NRF_GPIOTE->CONFIG[HAL_PALNA_GPIOTE_CHAN] =
	gpiote_palna.p_reg->CONFIG[gpiote_ch_palna] =
		(GPIOTE_CONFIG_MODE_Task <<
		 GPIOTE_CONFIG_MODE_Pos) |
		(NRF_GPIO_LNA_PSEL <<
@@ -1593,7 +1659,7 @@ void radio_gpio_pdn_setup(void)
{
	/* Note: the pdn-gpios property is optional. */
#if defined(NRF_GPIO_PDN)
	NRF_GPIOTE->CONFIG[HAL_PDN_GPIOTE_CHAN] =
	gpiote_pdn.p_reg->CONFIG[gpiote_ch_pdn] =
		(GPIOTE_CONFIG_MODE_Task <<
		 GPIOTE_CONFIG_MODE_Pos) |
		(NRF_GPIO_PDN_PSEL <<
@@ -1609,7 +1675,7 @@ void radio_gpio_csn_setup(void)
{
	/* Note: the spi-if property is optional. */
#if defined(NRF_GPIO_CSN_PIN)
	NRF_GPIOTE->CONFIG[HAL_CSN_GPIOTE_CHAN] =
	gpiote_csn.p_reg->CONFIG[gpiote_ch_csn] =
		(GPIOTE_CONFIG_MODE_Task <<
		 GPIOTE_CONFIG_MODE_Pos) |
		(NRF_GPIO_CSN_PSEL <<
@@ -1662,13 +1728,13 @@ void radio_gpio_pa_lna_disable(void)
					   BIT(HAL_DISABLE_PALNA_PPI) |
					   BIT(HAL_ENABLE_FEM_PPI) |
					   BIT(HAL_DISABLE_FEM_PPI));
	NRF_GPIOTE->CONFIG[HAL_PALNA_GPIOTE_CHAN] = 0;
	NRF_GPIOTE->CONFIG[HAL_PDN_GPIOTE_CHAN] = 0;
	NRF_GPIOTE->CONFIG[HAL_CSN_GPIOTE_CHAN] = 0;
	gpiote_palna.p_reg->CONFIG[gpiote_ch_palna] = 0;
	gpiote_pdn.p_reg->CONFIG[gpiote_ch_pdn] = 0;
	gpiote_csn.p_reg->CONFIG[gpiote_ch_csn] = 0;
#else
	hal_radio_nrf_ppi_channels_disable(BIT(HAL_ENABLE_PALNA_PPI) |
					   BIT(HAL_DISABLE_PALNA_PPI));
	NRF_GPIOTE->CONFIG[HAL_PALNA_GPIOTE_CHAN] = 0;
	gpiote_palna.p_reg->CONFIG[gpiote_ch_palna] = 0;
#endif
}
#endif /* HAL_RADIO_GPIO_HAVE_PA_PIN || HAL_RADIO_GPIO_HAVE_LNA_PIN */
+2 −0
Original line number Diff line number Diff line
@@ -156,6 +156,8 @@ uint32_t radio_tmr_tifs_base_get(void);
void radio_tmr_sample(void);
uint32_t radio_tmr_sample_get(void);

int radio_gpio_pa_lna_init(void);
void radio_gpio_pa_lna_deinit(void);
void radio_gpio_pa_setup(void);
void radio_gpio_lna_setup(void);
void radio_gpio_pdn_setup(void);
+0 −91
Original line number Diff line number Diff line
@@ -182,97 +182,6 @@ static inline void hal_trigger_rateoverride_ppi_config(void)
}
#endif /* CONFIG_BT_CTLR_PHY_CODED && CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */

/******************************************************************************/
#if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
static inline void hal_palna_ppi_setup(void)
{
	nrf_timer_publish_set(EVENT_TIMER, NRF_TIMER_EVENT_COMPARE2,
			      HAL_ENABLE_PALNA_PPI);
	nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_DISABLED,
			      HAL_DISABLE_PALNA_PPI);

#if !defined(HAL_RADIO_FEM_IS_NRF21540)
	nrf_gpiote_task_t task;

	task = nrf_gpiote_out_task_get(HAL_PALNA_GPIOTE_CHAN);
	nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_DISABLE_PALNA_PPI);
#endif
}
#endif /* defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || defined(HAL_RADIO_GPIO_HAVE_LNA_PIN) */

/******************************************************************************/
#if defined(HAL_RADIO_FEM_IS_NRF21540)

static inline void hal_pa_ppi_setup(void)
{
	nrf_gpiote_task_t task;

#if defined(HAL_RADIO_GPIO_PA_POL_INV)
	task = nrf_gpiote_clr_task_get(HAL_PALNA_GPIOTE_CHAN);
	nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_ENABLE_PALNA_PPI);
	task = nrf_gpiote_set_task_get(HAL_PALNA_GPIOTE_CHAN);
	nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_DISABLE_PALNA_PPI);
#else /* !HAL_RADIO_GPIO_PA_POL_INV */
	task = nrf_gpiote_set_task_get(HAL_PALNA_GPIOTE_CHAN);
	nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_ENABLE_PALNA_PPI);
	task = nrf_gpiote_clr_task_get(HAL_PALNA_GPIOTE_CHAN);
	nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_DISABLE_PALNA_PPI);
#endif /* !HAL_RADIO_GPIO_PA_POL_INV */
}

static inline void hal_lna_ppi_setup(void)
{
	nrf_gpiote_task_t task;

#if defined(HAL_RADIO_GPIO_LNA_POL_INV)
	task = nrf_gpiote_clr_task_get(HAL_PALNA_GPIOTE_CHAN);
	nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_ENABLE_PALNA_PPI);
	task = nrf_gpiote_set_task_get(HAL_PALNA_GPIOTE_CHAN);
	nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_DISABLE_PALNA_PPI);
#else /* !HAL_RADIO_GPIO_LNA_POL_INV */
	task = nrf_gpiote_set_task_get(HAL_PALNA_GPIOTE_CHAN);
	nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_ENABLE_PALNA_PPI);
	task = nrf_gpiote_clr_task_get(HAL_PALNA_GPIOTE_CHAN);
	nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_DISABLE_PALNA_PPI);
#endif /* !HAL_RADIO_GPIO_LNA_POL_INV */
}

static inline void hal_fem_ppi_setup(void)
{
	nrf_gpiote_task_t task;

	nrf_timer_publish_set(EVENT_TIMER, NRF_TIMER_EVENT_COMPARE3,
			      HAL_ENABLE_FEM_PPI);
	nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_DISABLED,
			      HAL_DISABLE_FEM_PPI);

#if defined(HAL_RADIO_GPIO_NRF21540_PDN_POL_INV)
	task = nrf_gpiote_clr_task_get(HAL_PDN_GPIOTE_CHAN);
	nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_ENABLE_FEM_PPI);
	task = nrf_gpiote_set_task_get(HAL_PDN_GPIOTE_CHAN);
	nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_DISABLE_FEM_PPI);
#else /* !HAL_RADIO_GPIO_NRF21540_PDN_POL_INV */
	task = nrf_gpiote_set_task_get(HAL_PDN_GPIOTE_CHAN);
	nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_ENABLE_FEM_PPI);
	task = nrf_gpiote_clr_task_get(HAL_PDN_GPIOTE_CHAN);
	nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_DISABLE_FEM_PPI);
#endif /* !HAL_RADIO_GPIO_NRF21540_PDN_POL_INV */

#if defined(HAL_RADIO_GPIO_NRF21540_CSN_POL_INV)
	task = nrf_gpiote_clr_task_get(HAL_CSN_GPIOTE_CHAN);
	nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_ENABLE_FEM_PPI);
	task = nrf_gpiote_set_task_get(HAL_CSN_GPIOTE_CHAN);
	nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_DISABLE_FEM_PPI);
#else /* !HAL_RADIO_GPIO_NRF21540_CSN_POL_INV */
	task = nrf_gpiote_set_task_get(HAL_CSN_GPIOTE_CHAN);
	nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_ENABLE_FEM_PPI);
	task = nrf_gpiote_clr_task_get(HAL_CSN_GPIOTE_CHAN);
	nrf_gpiote_subscribe_set(NRF_GPIOTE, task, HAL_DISABLE_FEM_PPI);
#endif /* !HAL_RADIO_GPIO_NRF21540_CSN_POL_INV */
}

#endif /* HAL_RADIO_FEM_IS_NRF21540 */

/******************************************************************************/
#if !defined(CONFIG_BT_CTLR_TIFS_HW)

+75 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2024 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/* Extracted from radio_nrf_dppi.h functions that reference gpiote variables. */

#if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
static inline void hal_palna_ppi_setup(void)
{
	nrf_timer_publish_set(EVENT_TIMER, NRF_TIMER_EVENT_COMPARE2,
			      HAL_ENABLE_PALNA_PPI);
	nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_DISABLED,
			      HAL_DISABLE_PALNA_PPI);

#if !defined(HAL_RADIO_FEM_IS_NRF21540)
	nrf_gpiote_task_t task;

	task = nrf_gpiote_out_task_get(gpiote_ch_palna);
	nrf_gpiote_subscribe_set(gpiote_palna.p_reg, task, HAL_DISABLE_PALNA_PPI);
#endif
}
#endif /* defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || defined(HAL_RADIO_GPIO_HAVE_LNA_PIN) */

/******************************************************************************/
#if defined(HAL_RADIO_FEM_IS_NRF21540)
static inline void hal_gpiote_tasks_setup(NRF_GPIOTE_Type *gpiote,
					  uint8_t gpiote_ch,
					  bool inv,
					  uint8_t ppi_ch_enable,
					  uint8_t ppi_ch_disable)
{
	nrf_gpiote_task_t task;

	task = inv ? nrf_gpiote_clr_task_get(gpiote_ch) :
		     nrf_gpiote_set_task_get(gpiote_ch);
	nrf_gpiote_subscribe_set(gpiote, task, ppi_ch_enable);

	task = inv ? nrf_gpiote_set_task_get(gpiote_ch) :
		     nrf_gpiote_clr_task_get(gpiote_ch);
	nrf_gpiote_subscribe_set(gpiote, task, ppi_ch_disable);
}

static inline void hal_pa_ppi_setup(void)
{
	hal_gpiote_tasks_setup(gpiote_palna.p_reg, gpiote_ch_palna,
			       IS_ENABLED(HAL_RADIO_GPIO_PA_POL_INV),
			       HAL_ENABLE_PALNA_PPI, HAL_DISABLE_PALNA_PPI);
}

static inline void hal_lna_ppi_setup(void)
{
	hal_gpiote_tasks_setup(gpiote_palna.p_reg, gpiote_ch_palna,
			       IS_ENABLED(HAL_RADIO_GPIO_LNA_POL_INV),
			       HAL_ENABLE_PALNA_PPI, HAL_DISABLE_PALNA_PPI);
}

static inline void hal_fem_ppi_setup(void)
{
	nrf_timer_publish_set(EVENT_TIMER, NRF_TIMER_EVENT_COMPARE3,
			      HAL_ENABLE_FEM_PPI);
	nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_DISABLED,
			      HAL_DISABLE_FEM_PPI);

	hal_gpiote_tasks_setup(gpiote_pdn.p_reg, gpiote_ch_pdn,
			       IS_ENABLED(HAL_RADIO_GPIO_NRF21540_PDN_POL_INV),
			       HAL_ENABLE_FEM_PPI, HAL_DISABLE_FEM_PPI);

	hal_gpiote_tasks_setup(gpiote_csn.p_reg, gpiote_ch_csn,
			       IS_ENABLED(HAL_RADIO_GPIO_NRF21540_CSN_POL_INV),
			       HAL_ENABLE_FEM_PPI, HAL_DISABLE_FEM_PPI);
}

#endif /* HAL_RADIO_FEM_IS_NRF21540 */
Loading