Commit 48c21fab authored by Vinayak Kariappa Chettimada's avatar Vinayak Kariappa Chettimada Committed by Carles Cufi
Browse files

Bluetooth: Controller: Fix radio_tmr_start_us to be soft realtime



Fix radio_tmr_start_us to be soft realtime, if the requested
start in microseconds is in the past, setup the next
earliest expiry. This is to prevent radio not being started
and not let the LLL hanging. When setup to receive auxiliary
PDU in LLL scheduling, is_aux_sched is set and if radio does
not start and the window is requested to be pre-empted, then
it is blocked from being preempted due to the is_aux_sched
flag remaining to be set. This stalls the scanning
infinitely until explicit scan disable.

Signed-off-by: default avatarVinayak Kariappa Chettimada <vich@nordicsemi.no>
parent 8b586ee5
Loading
Loading
Loading
Loading
+26 −21
Original line number Diff line number Diff line
@@ -1141,10 +1141,8 @@ uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t tick)
	return remainder_us;
}

void radio_tmr_start_us(uint8_t trx, uint32_t us)
uint32_t radio_tmr_start_us(uint8_t trx, uint32_t start_us)
{
	nrf_timer_cc_set(EVENT_TIMER, 0, us);

	hal_radio_enable_on_tick_ppi_config_and_enable(trx);

#if !defined(CONFIG_BT_CTLR_TIFS_HW)
@@ -1166,11 +1164,31 @@ void radio_tmr_start_us(uint8_t trx, uint32_t us)
	hal_sw_switch_timer_clear_ppi_config();
#endif /* CONFIG_SOC_SERIES_NRF53X */
#endif /* !CONFIG_BT_CTLR_TIFS_HW */

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

	/* Setup PPI 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 */
		EVENT_TIMER->EVENTS_COMPARE[0] = 0U;
		nrf_timer_cc_set(EVENT_TIMER, 0, start_us + 1U);

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

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

	return start_us + 1U;
}

uint32_t radio_tmr_start_now(uint8_t trx)
{
	uint32_t now, start;
	uint32_t start_us;

	hal_radio_enable_on_tick_ppi_config_and_enable(trx);

@@ -1193,25 +1211,12 @@ uint32_t radio_tmr_start_now(uint8_t trx)

	/* Capture the current time */
	nrf_timer_task_trigger(EVENT_TIMER, NRF_TIMER_TASK_CAPTURE1);
	now = EVENT_TIMER->CC[1];
	start = now;

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

		/* Setup compare event with min. 1 us offset */
		EVENT_TIMER->EVENTS_COMPARE[0] = 0U;
		nrf_timer_cc_set(EVENT_TIMER, 0, start + 1);

		/* Capture the current time */
		nrf_timer_task_trigger(EVENT_TIMER, NRF_TIMER_TASK_CAPTURE1);
	start_us = EVENT_TIMER->CC[1];

		now = EVENT_TIMER->CC[1];
	} while ((now > start) && (EVENT_TIMER->EVENTS_COMPARE[0] == 0U));
	/* Setup radio start at current time */
	start_us = radio_tmr_start_us(trx, start_us);

	return start + 1;
	return start_us;
}

uint32_t radio_tmr_start_get(void)
+1 −1
Original line number Diff line number Diff line
@@ -127,7 +127,7 @@ void radio_tmr_status_reset(void);
void radio_tmr_tifs_set(uint32_t tifs);
uint32_t radio_tmr_start(uint8_t trx, uint32_t ticks_start, uint32_t remainder);
uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t tick);
void radio_tmr_start_us(uint8_t trx, uint32_t us);
uint32_t radio_tmr_start_us(uint8_t trx, uint32_t us);
uint32_t radio_tmr_start_now(uint8_t trx);
uint32_t radio_tmr_start_get(void);
void radio_tmr_stop(void);
+8 −5
Original line number Diff line number Diff line
@@ -252,6 +252,7 @@ void lll_scan_aux_isr_aux_setup(void *param)
	uint32_t aux_offset_us;
	uint32_t aux_start_us;
	struct lll_scan *lll;
	uint32_t start_us;
	uint8_t phy_aux;
	uint32_t hcto;

@@ -336,13 +337,15 @@ void lll_scan_aux_isr_aux_setup(void *param)
	aux_start_us -= lll_radio_rx_ready_delay_get(phy_aux, PHY_FLAGS_S8);
	aux_start_us -= window_widening_us;
	aux_start_us -= EVENT_JITTER_US;
	radio_tmr_start_us(0, aux_start_us);

	start_us = radio_tmr_start_us(0, aux_start_us);

	/* Setup header complete timeout */
	hcto = ftr->radio_end_us + aux_offset_us;
	hcto += window_size_us;
	hcto += window_widening_us;
	hcto = start_us;
	hcto += EVENT_JITTER_US;
	hcto += window_widening_us;
	hcto += lll_radio_rx_ready_delay_get(phy_aux, PHY_FLAGS_S8);
	hcto += window_size_us;
	hcto += radio_rx_chain_delay_get(phy_aux, PHY_FLAGS_S8);
	hcto += addr_us_get(phy_aux);
	radio_tmr_hcto_configure(hcto);
@@ -358,7 +361,7 @@ void lll_scan_aux_isr_aux_setup(void *param)
#if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
	radio_gpio_lna_setup();

	radio_gpio_pa_lna_enable(aux_start_us +
	radio_gpio_pa_lna_enable(start_us +
				 radio_rx_ready_delay_get(phy_aux,
							  PHY_FLAGS_S8) -
				 HAL_RADIO_GPIO_LNA_OFFSET);
+8 −5
Original line number Diff line number Diff line
@@ -654,6 +654,7 @@ static void isr_aux_setup(void *param)
	uint32_t aux_offset_us;
	uint32_t aux_start_us;
	struct lll_sync *lll;
	uint32_t start_us;
	uint8_t phy_aux;
	uint32_t hcto;

@@ -736,13 +737,15 @@ static void isr_aux_setup(void *param)
	aux_start_us -= lll_radio_rx_ready_delay_get(phy_aux, PHY_FLAGS_S8);
	aux_start_us -= window_widening_us;
	aux_start_us -= EVENT_JITTER_US;
	radio_tmr_start_us(0, aux_start_us);

	start_us = radio_tmr_start_us(0, aux_start_us);

	/* Setup header complete timeout */
	hcto = ftr->radio_end_us + aux_offset_us;
	hcto += window_size_us;
	hcto += window_widening_us;
	hcto = start_us;
	hcto += EVENT_JITTER_US;
	hcto += window_widening_us;
	hcto += lll_radio_rx_ready_delay_get(phy_aux, PHY_FLAGS_S8);
	hcto += window_size_us;
	hcto += radio_rx_chain_delay_get(phy_aux, PHY_FLAGS_S8);
	hcto += addr_us_get(phy_aux);
	radio_tmr_hcto_configure(hcto);
@@ -758,7 +761,7 @@ static void isr_aux_setup(void *param)
#if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
	radio_gpio_lna_setup();

	radio_gpio_pa_lna_enable(aux_start_us +
	radio_gpio_pa_lna_enable(start_us +
				 radio_rx_ready_delay_get(phy_aux,
							  PHY_FLAGS_S8) -
				 HAL_RADIO_GPIO_LNA_OFFSET);
+2 −2
Original line number Diff line number Diff line
@@ -840,7 +840,7 @@ isr_rx_next_subevent:
		hcto -= (EVENT_CLOCK_JITTER_US << 1);

		start_us = hcto;
		radio_tmr_start_us(0U, start_us);
		hcto = radio_tmr_start_us(0U, start_us);

		/* Add 4 us + 4 us + (4 us * subevents so far), as radio
		 * was setup to listen 4 us early and subevents could have
@@ -858,7 +858,7 @@ isr_rx_next_subevent:
		hcto += radio_tmr_ready_restore();

		start_us = hcto;
		radio_tmr_start_us(0U, start_us);
		hcto = radio_tmr_start_us(0U, start_us);

		hcto += ((EVENT_JITTER_US + EVENT_TICKER_RES_MARGIN_US +
			  lll->window_widening_event_us) << 1) +