diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index d0c7a09e44f02..91d53ee57ba07 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -209,6 +209,12 @@ config BLUETOOTH_CONTROLLER_SCHED_ADVANCED Disabling this feature will lead to overlapping role in timespace leading to skipped events amongst active roles. +config BLUETOOTH_CONTROLLER_TIFS_HW + bool "H/w Accelerated tIFS Trx switching" + default y + help + Enable use of hardware accelerated tIFS Trx switching. + config BLUETOOTH_CONTROLLER_FAST_ENC bool "Fast Encryption Setup" help diff --git a/subsys/bluetooth/controller/hal/nrf5/radio.c b/subsys/bluetooth/controller/hal/nrf5/radio.c index e7c9a9c07e2e7..70de81687b255 100644 --- a/subsys/bluetooth/controller/hal/nrf5/radio.c +++ b/subsys/bluetooth/controller/hal/nrf5/radio.c @@ -229,24 +229,67 @@ void *radio_pkt_scratch_get(void) return _pkt_scratch; } +#if !defined(CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW) +static u8_t sw_tifs_toggle; + +static void sw_switch(u8_t dir) +{ + u8_t ppi = 12 + sw_tifs_toggle; + + NRF_PPI->CH[11].EEP = (u32_t)&(NRF_RADIO->EVENTS_END); + NRF_PPI->CH[11].TEP = (u32_t)&(NRF_PPI->TASKS_CHG[sw_tifs_toggle].EN); + NRF_PPI->CHENSET = PPI_CHEN_CH11_Msk; + + NRF_PPI->CH[ppi].EEP = (u32_t) + &(NRF_TIMER1->EVENTS_COMPARE[sw_tifs_toggle]); + if (dir) { + NRF_TIMER1->CC[sw_tifs_toggle] -= RADIO_TX_READY_DELAY_US + + RADIO_TX_CHAIN_DELAY_US; + NRF_PPI->CH[ppi].TEP = (u32_t)&(NRF_RADIO->TASKS_TXEN); + } else { + NRF_TIMER1->CC[sw_tifs_toggle] -= RADIO_RX_READY_DELAY_US; + NRF_PPI->CH[ppi].TEP = (u32_t)&(NRF_RADIO->TASKS_RXEN); + } + + sw_tifs_toggle += 1; + sw_tifs_toggle &= 1; +} +#endif /* CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ + void radio_switch_complete_and_rx(void) { - NRF_RADIO->SHORTS = - (RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk | - RADIO_SHORTS_DISABLED_RXEN_Msk); +#if defined(CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW) + NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | + RADIO_SHORTS_END_DISABLE_Msk | + RADIO_SHORTS_DISABLED_RXEN_Msk; +#else /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ + NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | + RADIO_SHORTS_END_DISABLE_Msk; + sw_switch(0); +#endif /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ } void radio_switch_complete_and_tx(void) { - NRF_RADIO->SHORTS = - (RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk | - RADIO_SHORTS_DISABLED_TXEN_Msk); +#if defined(CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW) + NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | + RADIO_SHORTS_END_DISABLE_Msk | + RADIO_SHORTS_DISABLED_TXEN_Msk; +#else /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ + NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | + RADIO_SHORTS_END_DISABLE_Msk; + sw_switch(1); +#endif /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ } void radio_switch_complete_and_disable(void) { NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk); + +#if !defined(CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW) + NRF_PPI->CHENCLR = PPI_CHEN_CH8_Msk | PPI_CHEN_CH11_Msk; +#endif /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ } void radio_rssi_measure(void) @@ -331,7 +374,11 @@ void radio_tmr_status_reset(void) void radio_tmr_tifs_set(u32_t tifs) { +#if defined(CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW) NRF_RADIO->TIFS = tifs; +#else /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ + NRF_TIMER1->CC[sw_tifs_toggle] = tifs; +#endif /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ } u32_t radio_tmr_start(u8_t trx, u32_t ticks_start, u32_t remainder) @@ -372,6 +419,29 @@ u32_t radio_tmr_start(u8_t trx, u32_t ticks_start, u32_t remainder) NRF_PPI->CHENSET = PPI_CHEN_CH0_Msk; } +#if !defined(CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW) + NRF_TIMER1->TASKS_CLEAR = 1; + NRF_TIMER1->MODE = 0; + NRF_TIMER1->PRESCALER = 4; + NRF_TIMER1->BITMODE = 0; /* 16 bit */ + NRF_TIMER1->TASKS_START = 1; + + NRF_PPI->CH[8].EEP = (u32_t)&(NRF_RADIO->EVENTS_END); + NRF_PPI->CH[8].TEP = (u32_t)&(NRF_TIMER1->TASKS_CLEAR); + NRF_PPI->CHENSET = PPI_CHEN_CH8_Msk; + + NRF_PPI->CH[9].EEP = (u32_t) + &(NRF_TIMER1->EVENTS_COMPARE[0]); + NRF_PPI->CH[9].TEP = (u32_t)&(NRF_PPI->TASKS_CHG[0].DIS); + + NRF_PPI->CH[10].EEP = (u32_t) + &(NRF_TIMER1->EVENTS_COMPARE[1]); + NRF_PPI->CH[10].TEP = (u32_t)&(NRF_PPI->TASKS_CHG[1].DIS); + + NRF_PPI->CHG[0] = PPI_CHG_CH9_Msk | PPI_CHG_CH12_Msk; + NRF_PPI->CHG[1] = PPI_CHG_CH10_Msk | PPI_CHG_CH13_Msk; +#endif /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ + return remainder; } @@ -379,6 +449,11 @@ void radio_tmr_stop(void) { NRF_TIMER0->TASKS_STOP = 1; NRF_TIMER0->TASKS_SHUTDOWN = 1; + +#if !defined(CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW) + NRF_TIMER1->TASKS_STOP = 1; + NRF_TIMER1->TASKS_SHUTDOWN = 1; +#endif /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ } void radio_tmr_hcto_configure(u32_t hcto) diff --git a/subsys/bluetooth/controller/ll_sw/ctrl.c b/subsys/bluetooth/controller/ll_sw/ctrl.c index b9eb36d84b004..f833316ccc9c0 100644 --- a/subsys/bluetooth/controller/ll_sw/ctrl.c +++ b/subsys/bluetooth/controller/ll_sw/ctrl.c @@ -37,7 +37,8 @@ #include #define RADIO_PREAMBLE_TO_ADDRESS_US 40 -#define RADIO_HCTO_US (150 + 2 + 2 + \ +#define RADIO_TIFS 150 +#define RADIO_HCTO_US (RADIO_TIFS + 2 + 2 + \ RADIO_PREAMBLE_TO_ADDRESS_US) #define RADIO_CONN_EVENTS(x, y) ((u16_t)((x) / (y))) @@ -511,6 +512,7 @@ static inline void isr_radio_state_tx(void) { _radio.state = STATE_RX; + radio_tmr_tifs_set(RADIO_TIFS); radio_switch_complete_and_tx(); radio_tmr_hcto_configure(radio_tmr_end_get() + @@ -1116,6 +1118,7 @@ static inline u32_t isr_rx_obs(u8_t irkmatch_id, u8_t rssi_ready) _radio.state = STATE_TX; radio_pkt_tx_set(pdu_adv_tx); + radio_tmr_tifs_set(RADIO_TIFS); radio_switch_complete_and_rx(); radio_tmr_end_capture(); @@ -2245,7 +2248,7 @@ static inline void isr_rx_conn(u8_t crc_ok, u8_t trx_done, radio_switch_complete_and_disable(); } } else { /* if (_radio.state == STATE_TX) */ - + radio_tmr_tifs_set(RADIO_TIFS); radio_switch_complete_and_rx(); radio_tmr_end_capture(); } @@ -2470,6 +2473,7 @@ static inline u32_t isr_close_obs(void) dont_close = 1; radio_pkt_rx_set(_radio.packet_rx[_radio.packet_rx_last]->pdu_data); + radio_tmr_tifs_set(RADIO_TIFS); radio_switch_complete_and_tx(); radio_rssi_measure(); @@ -4299,7 +4303,6 @@ static void adv_obs_conn_configure(u8_t phy) radio_reset(); radio_phy_set(phy); radio_tx_power_set(0); - radio_tmr_tifs_set(150); radio_isr_set(isr); } @@ -4352,6 +4355,7 @@ static void adv_setup(void) radio_pkt_tx_set(&_radio.advertiser.adv_data.data [_radio.advertiser.adv_data.first][0]); + radio_tmr_tifs_set(RADIO_TIFS); radio_switch_complete_and_rx(); bitmap = _radio.advertiser.chl_map_current; @@ -4576,6 +4580,7 @@ static void event_obs(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, } radio_pkt_rx_set(_radio.packet_rx[_radio.packet_rx_last]->pdu_data); + radio_tmr_tifs_set(RADIO_TIFS); radio_switch_complete_and_tx(); radio_rssi_measure(); @@ -5871,6 +5876,7 @@ static void event_slave(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, rx_packet_set(conn, (struct pdu_data *) _radio.packet_rx[_radio.packet_rx_last]->pdu_data); + radio_tmr_tifs_set(RADIO_TIFS); radio_switch_complete_and_tx(); #if defined(CONFIG_BLUETOOTH_CONTROLLER_CONN_RSSI) @@ -6008,6 +6014,7 @@ static void event_master(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, connection_configure(conn); tx_packet_set(conn, pdu_data_tx); + radio_tmr_tifs_set(RADIO_TIFS); radio_switch_complete_and_rx(); /* Setup Radio Channel */ @@ -6054,6 +6061,7 @@ static void event_master(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, rx_packet_set(conn, (struct pdu_data *)_radio. packet_rx[_radio.packet_rx_last]->pdu_data); + radio_tmr_tifs_set(RADIO_TIFS); radio_switch_complete_and_tx(); /* setup pkticker and hcto */