Bluetooth: controller: implement sw-switch with the event timer
This commit contributes the implementation of the sw-switch for tIFS in nRF5 Radio using the EVENT_TIMER instead of a dedicated TIMER instance. A Kconfig configuration is added so the user can select whether to use the EVENT_TIMER for the tIFS switch or use a dedicated TIMER instance. Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no> Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
0ec1095dd6
commit
2764084561
5 changed files with 97 additions and 2 deletions
|
@ -358,6 +358,19 @@ config BT_CTLR_TIFS_HW
|
|||
help
|
||||
Enable use of hardware accelerated tIFS Trx switching.
|
||||
|
||||
config BT_CTLR_SW_SWITCH_SINGLE_TIMER
|
||||
bool "Single TIMER tIFS Trx SW switching"
|
||||
depends on (!BT_CTLR_TIFS_HW) && SOC_SERIES_NRF52X
|
||||
help
|
||||
Implement the tIFS Trx SW switch with the same TIMER
|
||||
instance, as the one used for BLE event timing. Requires
|
||||
SW switching be enabled. Using a single TIMER:
|
||||
(+) frees up one TIMER instance
|
||||
(+) removes jitter for HCTO implementation
|
||||
(-) introduces drifting to the absolute time inside BLE
|
||||
events, that increases linearly with the number of
|
||||
packets exchanged in the event.
|
||||
|
||||
if BT_CONN
|
||||
|
||||
config BT_CTLR_FAST_ENC
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#error "Platform not defined."
|
||||
#endif
|
||||
|
||||
|
||||
static radio_isr_fp sfp_radio_isr;
|
||||
|
||||
void isr_radio(void)
|
||||
|
@ -301,10 +300,29 @@ u32_t radio_is_ready(void)
|
|||
return (NRF_RADIO->EVENTS_READY != 0);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
|
||||
static u32_t last_pdu_end_us;
|
||||
|
||||
u32_t radio_is_done(void)
|
||||
{
|
||||
if (NRF_RADIO->EVENTS_END != 0) {
|
||||
/* On packet END event increment last packet end time value.
|
||||
* Note: this depends on the function being called exactly once
|
||||
* in the ISR function.
|
||||
*/
|
||||
last_pdu_end_us += EVENT_TIMER->CC[2];
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
|
||||
u32_t radio_is_done(void)
|
||||
{
|
||||
return (NRF_RADIO->EVENTS_END != 0);
|
||||
}
|
||||
#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
|
||||
|
||||
u32_t radio_has_disabled(void)
|
||||
{
|
||||
|
@ -509,6 +527,13 @@ static void sw_switch(u8_t dir, u8_t phy_curr, u8_t flags_curr, u8_t phy_next,
|
|||
NRF_PPI_regw_sideeffects();
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
|
||||
/* Since the event timer is cleared on END, we
|
||||
* always need to capture the PDU END time-stamp.
|
||||
*/
|
||||
radio_tmr_end_capture();
|
||||
#endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
|
||||
|
||||
sw_tifs_toggle += 1;
|
||||
sw_tifs_toggle &= 1;
|
||||
}
|
||||
|
@ -706,6 +731,10 @@ u32_t radio_tmr_start(u8_t trx, u32_t ticks_start, u32_t remainder)
|
|||
#endif
|
||||
|
||||
#if !defined(CONFIG_BT_CTLR_TIFS_HW)
|
||||
#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
|
||||
last_pdu_end_us = 0;
|
||||
|
||||
#else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
|
||||
SW_SWITCH_TIMER->TASKS_CLEAR = 1;
|
||||
SW_SWITCH_TIMER->MODE = 0;
|
||||
SW_SWITCH_TIMER->PRESCALER = 4;
|
||||
|
@ -715,6 +744,7 @@ u32_t radio_tmr_start(u8_t trx, u32_t ticks_start, u32_t remainder)
|
|||
NRF_TIMER_regw_sideeffects_TASKS_CLEAR(SW_SWITCH_TIMER_NBR);
|
||||
NRF_TIMER_regw_sideeffects_TASKS_START(SW_SWITCH_TIMER_NBR);
|
||||
#endif
|
||||
#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
|
||||
|
||||
HAL_SW_SWITCH_TIMER_CLEAR_PPI_REGISTER_EVT =
|
||||
HAL_SW_SWITCH_TIMER_CLEAR_PPI_EVT;
|
||||
|
@ -890,6 +920,7 @@ void radio_tmr_end_capture(void)
|
|||
HAL_RADIO_END_TIME_CAPTURE_PPI_REGISTER_TASK =
|
||||
HAL_RADIO_END_TIME_CAPTURE_PPI_TASK;
|
||||
NRF_PPI->CHENSET = HAL_RADIO_END_TIME_CAPTURE_PPI_ENABLE;
|
||||
|
||||
#if defined(CONFIG_BOARD_NRFXX_NWTSIM)
|
||||
NRF_PPI_regw_sideeffects();
|
||||
#endif
|
||||
|
@ -897,7 +928,11 @@ void radio_tmr_end_capture(void)
|
|||
|
||||
u32_t radio_tmr_end_get(void)
|
||||
{
|
||||
#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
|
||||
return last_pdu_end_us;
|
||||
#else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
|
||||
return EVENT_TIMER->CC[2];
|
||||
#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
|
||||
}
|
||||
|
||||
u32_t radio_tmr_tifs_base_get(void)
|
||||
|
|
|
@ -181,13 +181,25 @@
|
|||
#endif /* !CONFIG_BT_CTLR_RADIO_ENABLE_FAST */
|
||||
|
||||
#if !defined(CONFIG_BT_CTLR_TIFS_HW)
|
||||
#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
|
||||
#undef EVENT_TIMER
|
||||
#define EVENT_TIMER NRF_TIMER4
|
||||
#define SW_SWITCH_TIMER EVENT_TIMER
|
||||
#define SW_SWITCH_TIMER_EVTS_COMP_BASE 4
|
||||
|
||||
#if defined(CONFIG_BOARD_NRFXX_NWTSIM)
|
||||
#define SW_SWITCH_TIMER_NBR 4
|
||||
#endif /* CONFIG_BOARD_NRFXX_NWTSIM */
|
||||
|
||||
#else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
|
||||
#define SW_SWITCH_TIMER NRF_TIMER1
|
||||
#define SW_SWITCH_TIMER_EVTS_COMP_BASE 0
|
||||
|
||||
#if defined(CONFIG_BOARD_NRFXX_NWTSIM)
|
||||
#define SW_SWITCH_TIMER_NBR 1
|
||||
#endif /* CONFIG_BOARD_NRFXX_NWTSIM */
|
||||
#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
|
||||
|
||||
#define SW_SWITCH_TIMER_EVTS_COMP_BASE 0
|
||||
#define SW_SWITCH_TIMER_TASK_GROUP_BASE 0
|
||||
#endif /* !CONFIG_BT_CTLR_TIFS_HW */
|
||||
|
||||
|
|
|
@ -338,9 +338,21 @@
|
|||
#endif /* !CONFIG_BT_CTLR_RADIO_ENABLE_FAST */
|
||||
|
||||
#if !defined(CONFIG_BT_CTLR_TIFS_HW)
|
||||
#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
|
||||
#undef EVENT_TIMER
|
||||
#define EVENT_TIMER NRF_TIMER4
|
||||
#define SW_SWITCH_TIMER EVENT_TIMER
|
||||
#define SW_SWITCH_TIMER_EVTS_COMP_BASE 3
|
||||
#define SW_SWITCH_TIMER_EVTS_COMP_S2_BASE 5
|
||||
#undef HAL_EVENT_TIMER_SAMPLE_CC_OFFSET
|
||||
#define HAL_EVENT_TIMER_SAMPLE_CC_OFFSET 2
|
||||
|
||||
#else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
|
||||
#define SW_SWITCH_TIMER NRF_TIMER1
|
||||
#define SW_SWITCH_TIMER_EVTS_COMP_BASE 0
|
||||
#define SW_SWITCH_TIMER_EVTS_COMP_S2_BASE 2
|
||||
#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
|
||||
|
||||
#define SW_SWITCH_TIMER_TASK_GROUP_BASE 0
|
||||
#endif /* !CONFIG_BT_CTLR_TIFS_HW */
|
||||
|
||||
|
|
|
@ -214,20 +214,43 @@ static inline void hal_radio_enable_on_tick_ppi_config_and_enable(u8_t trx)
|
|||
#if !defined(CONFIG_BT_CTLR_TIFS_HW)
|
||||
/* PPI setup used for SW-based auto-switching during TIFS. */
|
||||
|
||||
#if !defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
|
||||
/* Clear SW-switch timer on packet end:
|
||||
* wire the RADIO EVENTS_END event to SW_SWITCH_TIMER TASKS_CLEAR task.
|
||||
*
|
||||
* Note: this PPI is not needed if we use a single TIMER instance in radio.c
|
||||
*/
|
||||
#define HAL_SW_SWITCH_TIMER_CLEAR_PPI 7
|
||||
#define HAL_SW_SWITCH_TIMER_CLEAR_PPI_ENABLE \
|
||||
((PPI_CHENSET_CH7_Set << PPI_CHENSET_CH7_Pos) & PPI_CHENSET_CH7_Msk)
|
||||
#define HAL_SW_SWITCH_TIMER_CLEAR_PPI_DISABLE \
|
||||
((PPI_CHENCLR_CH7_Clear << PPI_CHENCLR_CH7_Pos) & PPI_CHENCLR_CH7_Msk)
|
||||
#else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
|
||||
|
||||
/* Clear event timer (sw-switch timer) on Radio end:
|
||||
* wire the RADIO EVENTS_END event to the
|
||||
* EVENT_TIMER TASKS_CLEAR task.
|
||||
*
|
||||
* Note: in nRF52X PPI 5 is forked for both capturing and clearing timer
|
||||
* on RADIO EVENTS_END.
|
||||
*/
|
||||
#define HAL_SW_SWITCH_TIMER_CLEAR_PPI 5
|
||||
#define HAL_SW_SWITCH_TIMER_CLEAR_PPI_ENABLE \
|
||||
((PPI_CHENSET_CH5_Set << PPI_CHENSET_CH5_Pos) & PPI_CHENSET_CH5_Msk)
|
||||
#define HAL_SW_SWITCH_TIMER_CLEAR_PPI_DISABLE \
|
||||
((PPI_CHENCLR_CH5_Clear << PPI_CHENCLR_CH5_Pos) & PPI_CHENCLR_CH5_Msk)
|
||||
#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
|
||||
#define HAL_SW_SWITCH_TIMER_CLEAR_PPI_REGISTER_EVT \
|
||||
NRF_PPI->CH[HAL_SW_SWITCH_TIMER_CLEAR_PPI].EEP
|
||||
#define HAL_SW_SWITCH_TIMER_CLEAR_PPI_EVT \
|
||||
((u32_t)&(NRF_RADIO->EVENTS_END))
|
||||
#if !defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
|
||||
#define HAL_SW_SWITCH_TIMER_CLEAR_PPI_REGISTER_TASK \
|
||||
NRF_PPI->CH[HAL_SW_SWITCH_TIMER_CLEAR_PPI].TEP
|
||||
#else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
|
||||
#define HAL_SW_SWITCH_TIMER_CLEAR_PPI_REGISTER_TASK \
|
||||
NRF_PPI->FORK[HAL_SW_SWITCH_TIMER_CLEAR_PPI].TEP
|
||||
#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
|
||||
#define HAL_SW_SWITCH_TIMER_CLEAR_PPI_TASK \
|
||||
((u32_t)&(SW_SWITCH_TIMER->TASKS_CLEAR))
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue