Commit ba1def1a authored by Vinayak Kariappa Chettimada's avatar Vinayak Kariappa Chettimada Committed by Fabio Baltieri
Browse files

Bluetooth: Controller: Add radio timer ISR usage support

Add radio timer ISR usage support.

Signed-off-by: default avatarVinayak Kariappa Chettimada <vich@nordicsemi.no>
parent d9f890bf
Loading
Loading
Loading
Loading
+7 −0
Changes for subsys/bluetooth/controller/Kconfig.ll_sw_split: 7 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -902,6 +902,13 @@ config BT_CTLR_RADIO_ENABLE_FAST
	help
	  Enable use of fast radio ramp-up mode.

config BT_CTLR_RADIO_TIMER_ISR
	# Hidden, enables use of timer ISR callback
	bool
	depends on SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF53X
	help
	  Enables use of timer ISR callback.

config BT_CTLR_TIFS_HW
	bool "H/w Accelerated tIFS Trx switching"
	depends on !BT_CTLR_RADIO_ENABLE_FAST && BT_CTLR_TIFS_HW_SUPPORT
+50 −0
Changes for subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c: 50 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -1153,6 +1153,56 @@ uint32_t radio_bc_has_match(void)
	return (NRF_RADIO->EVENTS_BCMATCH != 0);
}

#if defined(CONFIG_BT_CTLR_RADIO_TIMER_ISR)
static radio_isr_cb_t isr_radio_tmr_cb;
static void           *isr_radio_tmr_cb_param;

void isr_radio_tmr(void)
{
	irq_disable(TIMER0_IRQn);
	nrf_timer_int_disable(EVENT_TIMER, TIMER_INTENSET_COMPARE2_Msk);
	nrf_timer_event_clear(EVENT_TIMER, HAL_EVENT_TIMER_DEFERRED_TX_EVENT);

	isr_radio_tmr_cb(isr_radio_tmr_cb_param);
}

uint32_t radio_tmr_isr_set(uint32_t start_us, radio_isr_cb_t cb, void *param)
{
	irq_disable(TIMER0_IRQn);

	isr_radio_tmr_cb_param = param;
	isr_radio_tmr_cb = cb;

	/* start_us could be the current count in the timer */
	uint32_t now_us = start_us;

	/* Setup timer compare while determining the latency in doing so */
	do {
		/* Set start to be, now plus the determined latency */
		start_us = (now_us << 1) - start_us;

		/* Setup compare event with min. 1 us offset */
		nrf_timer_event_clear(EVENT_TIMER, HAL_EVENT_TIMER_DEFERRED_TX_EVENT);
		nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_DEFERRED_TRX_CC_OFFSET,
				 start_us + 1U);

		/* Capture the current time */
		nrf_timer_task_trigger(EVENT_TIMER, HAL_EVENT_TIMER_SAMPLE_TASK);

		now_us = EVENT_TIMER->CC[HAL_EVENT_TIMER_SAMPLE_CC_OFFSET];
	} while ((now_us > start_us) &&
		 (EVENT_TIMER->EVENTS_COMPARE[HAL_EVENT_TIMER_DEFERRED_TRX_CC_OFFSET] == 0U));

	nrf_timer_int_enable(EVENT_TIMER, TIMER_INTENSET_COMPARE2_Msk);

	NVIC_ClearPendingIRQ(TIMER0_IRQn);

	irq_enable(TIMER0_IRQn);

	return start_us + 1U;
}
#endif /* CONFIG_BT_CTLR_RADIO_TIMER_ISR */

void radio_tmr_status_reset(void)
{
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
+3 −0
Changes for subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h: 3 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -130,6 +130,9 @@ void radio_bc_configure(uint32_t n);
void radio_bc_status_reset(void);
uint32_t radio_bc_has_match(void);

void isr_radio_tmr(void);
uint32_t radio_tmr_isr_set(uint32_t start_us, radio_isr_cb_t cb, void *param);

void radio_tmr_status_reset(void);
void radio_tmr_tx_status_reset(void);
void radio_tmr_rx_status_reset(void);
+45 −0
Changes for subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c: 45 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -115,6 +115,33 @@ ISR_DIRECT_DECLARE(radio_nrf5_isr)
#endif /* !CONFIG_DYNAMIC_DIRECT_INTERRUPTS */
}

#if defined(CONFIG_BT_CTLR_RADIO_TIMER_ISR)
#if defined(CONFIG_BT_CTLR_DYNAMIC_INTERRUPTS) && \
	defined(CONFIG_DYNAMIC_DIRECT_INTERRUPTS)
static void timer_nrf5_isr(const void *arg)
#else /* !CONFIG_BT_CTLR_DYNAMIC_INTERRUPTS */
ISR_DIRECT_DECLARE(timer_nrf5_isr)
#endif /* !CONFIG_BT_CTLR_DYNAMIC_INTERRUPTS */
{
	DEBUG_RADIO_ISR(1);

	lll_prof_enter_radio();

	isr_radio_tmr();

	ISR_DIRECT_PM();

	lll_prof_exit_radio();

	DEBUG_RADIO_ISR(0);

#if !defined(CONFIG_BT_CTLR_DYNAMIC_INTERRUPTS) || \
	!defined(CONFIG_DYNAMIC_DIRECT_INTERRUPTS)
	return 1;
#endif /* !CONFIG_DYNAMIC_DIRECT_INTERRUPTS */
}
#endif /* CONFIG_BT_CTLR_RADIO_TIMER_ISR */

static void rtc0_nrf5_isr(const void *arg)
{
	DEBUG_TICKER_ISR(1);
@@ -221,9 +248,19 @@ int lll_init(void)
				       IRQ_CONNECT_FLAGS, no_reschedule);
	irq_connect_dynamic(HAL_RADIO_IRQn, CONFIG_BT_CTLR_LLL_PRIO,
			    radio_nrf5_isr, NULL, IRQ_CONNECT_FLAGS);
#if defined(CONFIG_BT_CTLR_RADIO_TIMER_ISR)
	ARM_IRQ_DIRECT_DYNAMIC_CONNECT(TIMER0_IRQn, CONFIG_BT_CTLR_LLL_PRIO,
				       IRQ_CONNECT_FLAGS, no_reschedule);
	irq_connect_dynamic(TIMER0_IRQn, CONFIG_BT_CTLR_LLL_PRIO,
			    timer_nrf5_isr, NULL, IRQ_CONNECT_FLAGS);
#endif /* CONFIG_BT_CTLR_RADIO_TIMER_ISR */
#else /* !CONFIG_DYNAMIC_DIRECT_INTERRUPTS */
	IRQ_DIRECT_CONNECT(HAL_RADIO_IRQn, CONFIG_BT_CTLR_LLL_PRIO,
			   radio_nrf5_isr, IRQ_CONNECT_FLAGS);
#if defined(CONFIG_BT_CTLR_RADIO_TIMER_ISR)
	IRQ_DIRECT_CONNECT(TIMER0_IRQn, CONFIG_BT_CTLR_LLL_PRIO,
			   timer_nrf5_isr, IRQ_CONNECT_FLAGS);
#endif /* CONFIG_BT_CTLR_RADIO_TIMER_ISR */
#endif /* !CONFIG_DYNAMIC_DIRECT_INTERRUPTS */
	irq_connect_dynamic(HAL_RTC_IRQn, CONFIG_BT_CTLR_ULL_HIGH_PRIO,
			    rtc0_nrf5_isr, NULL, 0U);
@@ -238,6 +275,10 @@ int lll_init(void)
#else /* !CONFIG_BT_CTLR_DYNAMIC_INTERRUPTS */
	IRQ_DIRECT_CONNECT(HAL_RADIO_IRQn, CONFIG_BT_CTLR_LLL_PRIO,
			   radio_nrf5_isr, IRQ_CONNECT_FLAGS);
#if defined(CONFIG_BT_CTLR_RADIO_TIMER_ISR)
	IRQ_DIRECT_CONNECT(TIMER0_IRQn, CONFIG_BT_CTLR_LLL_PRIO,
			   timer_nrf5_isr, IRQ_CONNECT_FLAGS);
#endif /* CONFIG_BT_CTLR_RADIO_TIMER_ISR */
	IRQ_CONNECT(HAL_RTC_IRQn, CONFIG_BT_CTLR_ULL_HIGH_PRIO,
		    rtc0_nrf5_isr, NULL, 0);
#if defined(CONFIG_BT_CTLR_ZLI)
@@ -298,6 +339,10 @@ int lll_deinit(void)
#if defined(CONFIG_DYNAMIC_DIRECT_INTERRUPTS)
	irq_disconnect_dynamic(HAL_RADIO_IRQn, CONFIG_BT_CTLR_LLL_PRIO,
			       radio_nrf5_isr, NULL, IRQ_CONNECT_FLAGS);
#if defined(CONFIG_BT_CTLR_RADIO_TIMER_ISR)
	irq_disconnect_dynamic(TIMER0_IRQn, CONFIG_BT_CTLR_LLL_PRIO,
			       timer_nrf5_isr, NULL, IRQ_CONNECT_FLAGS);
#endif /* CONFIG_BT_CTLR_RADIO_TIMER_ISR */
#endif /* CONFIG_DYNAMIC_DIRECT_INTERRUPTS */
	irq_disconnect_dynamic(HAL_RTC_IRQn, CONFIG_BT_CTLR_ULL_HIGH_PRIO,
			       rtc0_nrf5_isr, NULL, 0U);