Skip to content

Commit

Permalink
Bluetooth: controller: PHY Update Procedure
Browse files Browse the repository at this point in the history
Add support for Bluetooth v5.0 PHY Update Procedure.

Jira: ZEP-2086

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
  • Loading branch information
cvinayak committed May 5, 2017
1 parent bdaa7ba commit 3fe6eaf
Show file tree
Hide file tree
Showing 9 changed files with 742 additions and 130 deletions.
8 changes: 8 additions & 0 deletions subsys/bluetooth/controller/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,13 @@ config BLUETOOTH_CONTROLLER_CHAN_SEL_2
Enable support for Bluetooth 5.0 LE Channel Selection Algorithm #2 in
the Controller.

config BLUETOOTH_CONTROLLER_PHY
bool "PHY Update"
default y
help
Enable support for Bluetooth 5.0 PHY Update Procedure in the
Controller.

config BLUETOOTH_CONTROLLER_ADVANCED_FEATURES
bool "Show advanced features"
help
Expand Down Expand Up @@ -211,6 +218,7 @@ config BLUETOOTH_CONTROLLER_SCHED_ADVANCED

config BLUETOOTH_CONTROLLER_TIFS_HW
bool "H/w Accelerated tIFS Trx switching"
depends on !BLUETOOTH_CONTROLLER_PHY
default y
help
Enable use of hardware accelerated tIFS Trx switching.
Expand Down
88 changes: 59 additions & 29 deletions subsys/bluetooth/controller/hal/nrf5/radio.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,42 @@ void radio_reset(void)
RADIO_POWER_POWER_Msk);
}

void radio_phy_set(u8_t phy)
void radio_phy_set(u8_t phy, u8_t flags)
{
NRF_RADIO->MODE =
(((phy) ? (u32_t)phy : RADIO_MODE_MODE_Ble_1Mbit) <<
RADIO_MODE_MODE_Pos) & RADIO_MODE_MODE_Msk;
u32_t mode;

switch (phy) {
case BIT(0):
default:
mode = RADIO_MODE_MODE_Ble_1Mbit;
break;

#if defined(CONFIG_SOC_SERIES_NRF51X)
case BIT(1):
mode = RADIO_MODE_MODE_Nrf_2Mbit;
break;

#elif defined(CONFIG_SOC_SERIES_NRF52X)
case BIT(1):
mode = RADIO_MODE_MODE_Ble_2Mbit;
break;

#else /* !CONFIG_SOC_SERIES_NRF52X */
case BIT(1):
mode = RADIO_MODE_MODE_Ble_2Mbit;
break;

case BIT(2):
if (flags & 0x01) {
mode = RADIO_MODE_MODE_Ble_LR500Kbit;
} else {
mode = RADIO_MODE_MODE_Ble_LR125Kbit;
}
break;
#endif /* !CONFIG_SOC_SERIES_NRF52X */
}

NRF_RADIO->MODE = (mode << RADIO_MODE_MODE_Pos) & RADIO_MODE_MODE_Msk;
}

void radio_tx_power_set(u32_t power)
Expand Down Expand Up @@ -96,12 +127,12 @@ void radio_aa_set(u8_t *aa)

void radio_pkt_configure(u8_t bits_len, u8_t max_len, u8_t flags)
{
u8_t p16 = (flags >> 1) & 0x01; /* 16-bit preamble */
u8_t dc = flags & 0x01; /* Adv or Data channel */
u32_t extra;
u8_t phy;

#if defined(CONFIG_SOC_SERIES_NRF51X)
ARG_UNUSED(p16);
ARG_UNUSED(phy);

extra = 0;

Expand All @@ -110,8 +141,28 @@ void radio_pkt_configure(u8_t bits_len, u8_t max_len, u8_t flags)
bits_len = 5;
}
#else /* !CONFIG_SOC_SERIES_NRF51X */
extra = (((p16) ? RADIO_PCNF0_PLEN_16bit : RADIO_PCNF0_PLEN_8bit) <<
RADIO_PCNF0_PLEN_Pos) & RADIO_PCNF0_PLEN_Msk;
extra = 0;

phy = (flags >> 1) & 0x07; /* phy */
switch (phy) {
case BIT(0):
default:
extra |= (RADIO_PCNF0_PLEN_8bit << RADIO_PCNF0_PLEN_Pos) &
RADIO_PCNF0_PLEN_Msk;
break;

case BIT(1):
extra |= (RADIO_PCNF0_PLEN_16bit << RADIO_PCNF0_PLEN_Pos) &
RADIO_PCNF0_PLEN_Msk;
break;

#if !defined(CONFIG_SOC_SERIES_NRF52X)
case BIT(2):
extra |= (RADIO_PCNF0_PLEN_LongRange << RADIO_PCNF0_PLEN_Pos) &
RADIO_PCNF0_PLEN_Msk;
break;
#endif
}

/* To use same Data Channel PDU structure with nRF5 specific overhead
* byte, include the S1 field in radio packet configuration.
Expand Down Expand Up @@ -555,28 +606,7 @@ void *radio_ccm_tx_pkt_set(struct ccm *ccm, void *pkt)
NRF_CCM->EVENTS_ENDCRYPT = 0;
NRF_CCM->EVENTS_ERROR = 0;

#if defined(CONFIG_SOC_SERIES_NRF51X)
/* set up PPI to enable CCM */
NRF_PPI->CH[6].EEP = (u32_t)&(NRF_RADIO->EVENTS_READY);
NRF_PPI->CH[6].TEP = (u32_t)&(NRF_CCM->TASKS_KSGEN);
NRF_PPI->CHENSET = PPI_CHEN_CH6_Msk;
#elif 0
/* encrypt tx packet */
NRF_CCM->INTENSET = CCM_INTENSET_ENDCRYPT_Msk;
NRF_CCM->TASKS_KSGEN = 1;
while (NRF_CCM->EVENTS_ENDCRYPT == 0) {
__WFE();
__SEV();
__WFE();
}
NRF_CCM->INTENCLR = CCM_INTENCLR_ENDCRYPT_Msk;
NVIC_ClearPendingIRQ(CCM_AAR_IRQn);

LL_ASSERT(NRF_CCM->EVENTS_ERROR == 0);
#else
/* start KSGEN early, but dont wait for ENDCRYPT */
NRF_CCM->TASKS_KSGEN = 1;
#endif

return _pkt_scratch;
}
Expand Down
2 changes: 1 addition & 1 deletion subsys/bluetooth/controller/hal/radio.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ void isr_radio(void);
void radio_isr_set(radio_isr_fp fp_radio_isr);

void radio_reset(void);
void radio_phy_set(u8_t phy);
void radio_phy_set(u8_t phy, u8_t flags);
void radio_tx_power_set(u32_t power);
void radio_freq_chan_set(u32_t chan);
void radio_whiten_iv_set(u32_t iv);
Expand Down
36 changes: 36 additions & 0 deletions subsys/bluetooth/controller/hci/hci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1339,6 +1339,33 @@ static void le_chan_sel_algo(struct pdu_data *pdu_data, u16_t handle,
}
#endif /* CONFIG_BLUETOOTH_CONTROLLER_CHAN_SEL_2 */

#if defined(CONFIG_BLUETOOTH_CONTROLLER_PHY)
static void le_phy_upd_complete(struct pdu_data *pdu_data, u16_t handle,
struct net_buf *buf)
{
struct bt_hci_evt_le_phy_update_complete *sep;
struct radio_le_phy_upd_cmplt *radio_le_phy_upd_cmplt;

radio_le_phy_upd_cmplt = (struct radio_le_phy_upd_cmplt *)
pdu_data->payload.lldata;

if (!(event_mask & BT_EVT_MASK_LE_META_EVENT) ||
!(le_event_mask & BT_EVT_MASK_LE_PHY_UPDATE_COMPLETE)) {
BT_WARN("handle: 0x%04x, tx: %x, rx: %x.", handle,
radio_le_phy_upd_cmplt->tx,
radio_le_phy_upd_cmplt->rx);
return;
}

sep = meta_evt(buf, BT_HCI_EVT_LE_PHY_UPDATE_COMPLETE, sizeof(*sep));

sep->status = 0x00;
sep->handle = sys_cpu_to_le16(handle);
sep->tx_phy = radio_le_phy_upd_cmplt->tx;
sep->rx_phy = radio_le_phy_upd_cmplt->rx;
}
#endif /* CONFIG_BLUETOOTH_CONTROLLER_CHAN_SEL_2 */

static void encode_control(struct radio_pdu_node_rx *node_rx,
struct pdu_data *pdu_data, struct net_buf *buf)
{
Expand Down Expand Up @@ -1382,6 +1409,12 @@ static void encode_control(struct radio_pdu_node_rx *node_rx,
break;
#endif /* CONFIG_BLUETOOTH_CONTROLLER_CHAN_SEL_2 */

#if defined(CONFIG_BLUETOOTH_CONTROLLER_PHY)
case NODE_RX_TYPE_PHY_UPDATE:
le_phy_upd_complete(pdu_data, handle, buf);
return;
#endif /* CONFIG_BLUETOOTH_CONTROLLER_PHY */

#if defined(CONFIG_BLUETOOTH_CONTROLLER_CONN_RSSI)
case NODE_RX_TYPE_RSSI:
BT_INFO("handle: 0x%04x, rssi: -%d dB.", handle,
Expand Down Expand Up @@ -1717,6 +1750,9 @@ s8_t hci_get_class(struct radio_pdu_node_rx *node_rx)
#if defined(CONFIG_BLUETOOTH_CONTROLLER_CHAN_SEL_2)
case NODE_RX_TYPE_CHAN_SEL_ALGO:
#endif
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PHY)
case NODE_RX_TYPE_PHY_UPDATE:
#endif /* CONFIG_BLUETOOTH_CONTROLLER_PHY */
return HCI_CLASS_EVT_CONNECTION;
default:
return -1;
Expand Down
4 changes: 4 additions & 0 deletions subsys/bluetooth/controller/include/ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,8 @@ void ll_length_max_get(u16_t *max_tx_octets, u16_t *max_tx_time,
u16_t *max_rx_octets, u16_t *max_rx_time);
#endif /* CONFIG_BLUETOOTH_CONTROLLER_DATA_LENGTH */

#if defined(CONFIG_BLUETOOTH_CONTROLLER_PHY)
u32_t ll_phy_req_send(u16_t handle, u8_t tx, u8_t rx);
#endif /* CONFIG_BLUETOOTH_CONTROLLER_PHY */

#endif /* _LL_H_ */
Loading

0 comments on commit 3fe6eaf

Please sign in to comment.