Skip to content

Commit

Permalink
Bluetooth: controller: Introduce s/w based TRX switching
Browse files Browse the repository at this point in the history
Introduce alternative TRX switching using dedicated timers
and peripheral interconnect. This will enable the
possibility to independently configure the Tx and Rx
settings between the tIFS.

Note, this will also provide the opportunity to design a
soft realtime Radio ISR.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
  • Loading branch information
cvinayak authored and jhedberg committed May 4, 2017
1 parent ad4bb37 commit 75bff19
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 9 deletions.
6 changes: 6 additions & 0 deletions subsys/bluetooth/controller/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
87 changes: 81 additions & 6 deletions subsys/bluetooth/controller/hal/nrf5/radio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -372,13 +419,41 @@ 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;
}

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)
Expand Down
14 changes: 11 additions & 3 deletions subsys/bluetooth/controller/ll_sw/ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
#include <bluetooth/log.h>

#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)))

Expand Down Expand Up @@ -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() +
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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();
}
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */
Expand Down

0 comments on commit 75bff19

Please sign in to comment.