nimble/controller: Add configuration for LE Coded PHY This patch adds nRF52 configuration for LE Coded PHY.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/24131d55 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/24131d55 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/24131d55 Branch: refs/heads/bluetooth5 Commit: 24131d55f6f67f7015f7098d7fb2a3004abb6a84 Parents: 1f5c04d Author: Andrzej Kaczmarek <[email protected]> Authored: Sat Apr 29 00:55:31 2017 +0200 Committer: Andrzej Kaczmarek <[email protected]> Committed: Wed May 17 11:56:17 2017 +0200 ---------------------------------------------------------------------- hw/drivers/nimble/nrf52/src/ble_phy.c | 40 ++++++++++++++++++++++++---- net/nimble/controller/src/ble_ll_conn.c | 4 ++- 2 files changed, 38 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/24131d55/hw/drivers/nimble/nrf52/src/ble_phy.c ---------------------------------------------------------------------- diff --git a/hw/drivers/nimble/nrf52/src/ble_phy.c b/hw/drivers/nimble/nrf52/src/ble_phy.c index a1da61e..a9d0150 100644 --- a/hw/drivers/nimble/nrf52/src/ble_phy.c +++ b/hw/drivers/nimble/nrf52/src/ble_phy.c @@ -51,6 +51,8 @@ extern uint32_t g_nrf_irk_list[]; */ #define NRF_LFLEN_BITS (8) #define NRF_S0_LEN (1) +#define NRF_CI_LEN (2) +#define NRF_TERM_LEN (3) /* Maximum length of frames */ #define NRF_MAXLEN (255) @@ -77,7 +79,7 @@ struct ble_phy_obj uint8_t phy_tx_pyld_len; uint8_t phy_txtorx_phy_mode; uint8_t phy_cur_phy_mode; - uint8_t phy_mode_pkt_start_off[BLE_PHY_NUM_MODULATIONS]; + uint16_t phy_mode_pkt_start_off[BLE_PHY_NUM_MODULATIONS]; uint32_t phy_aar_scratch; uint32_t phy_access_address; uint32_t phy_pcnf0; @@ -189,6 +191,17 @@ struct nrf_ccm_data g_nrf_ccm_data; #endif #if (BLE_LL_BT5_PHY_SUPPORTED == 1) + +static inline int ble_phy_pdu_coded_dur(int pyld_len, int s) +{ + /* + * Specification provides duration for each PDU field directly in us so we + * can use them directly here (Vol 6, Part B, 2.2). + */ + return 80 + 256 + 16 + 24 + /* Preamble + Access Address + CI + TERM1 */ + s * ((BLE_LL_PDU_HDR_LEN + pyld_len) * 8 + 24 + 3); /* PDU + CRC + TERM2 */ +} + /** * Calculate the length of BLE PDU * @@ -216,15 +229,19 @@ ble_phy_mode_pdu_dur(uint8_t pyld_len, int phy_mode) /* 4 usecs per byte */ usecs = (pyld_len + (2 * BLE_LL_PREAMBLE_LEN) + BLE_LL_ACC_ADDR_LEN + BLE_LL_CRC_LEN + BLE_LL_PDU_HDR_LEN) << 2; + } else if (phy_mode == BLE_PHY_MODE_CODED_125KBPS) { + usecs = ble_phy_pdu_coded_dur(pyld_len, 8); + } else if (phy_mode == BLE_PHY_MODE_CODED_500KBPS) { + usecs = ble_phy_pdu_coded_dur(pyld_len, 2); } else { - /* XXX: TODO implement */ assert(0); } return usecs; } -/* Packet start offset (in usecs). This is the preamble plus access address. */ +/* Packet start offset (in usecs). This is the preamble plus access address. + * For LE Coded PHY this also includes CI and TERM1. */ uint32_t ble_phy_mode_pdu_start_off(int phy_mode) { @@ -241,10 +258,22 @@ ble_phy_mode_set(int cur_phy_mode, int txtorx_phy_mode) NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_2Mbit; NRF_RADIO->PCNF0 = g_ble_phy_data.phy_pcnf0 | (RADIO_PCNF0_PLEN_16bit << RADIO_PCNF0_PLEN_Pos); + } else if (cur_phy_mode == BLE_PHY_MODE_CODED_125KBPS) { + NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_LR125Kbit; + NRF_RADIO->PCNF0 = g_ble_phy_data.phy_pcnf0 | + (RADIO_PCNF0_PLEN_LongRange << RADIO_PCNF0_PLEN_Pos) | + (NRF_CI_LEN << RADIO_PCNF0_CILEN_Pos) | + (NRF_TERM_LEN << RADIO_PCNF0_TERMLEN_Pos); + } else if (cur_phy_mode == BLE_PHY_MODE_CODED_500KBPS) { + NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_LR500Kbit; + NRF_RADIO->PCNF0 = g_ble_phy_data.phy_pcnf0 | + (RADIO_PCNF0_PLEN_LongRange << RADIO_PCNF0_PLEN_Pos) | + (NRF_CI_LEN << RADIO_PCNF0_CILEN_Pos) | + (NRF_TERM_LEN << RADIO_PCNF0_TERMLEN_Pos); } else { - /* XXX: TODO added coded PHY */ assert(0); } + g_ble_phy_data.phy_cur_phy_mode = (uint8_t)cur_phy_mode; g_ble_phy_data.phy_txtorx_phy_mode = (uint8_t)txtorx_phy_mode; } @@ -898,10 +927,11 @@ ble_phy_init(void) { int rc; - /* XXX: TODO add coded phy */ /* Set packet start offsets for various phys */ g_ble_phy_data.phy_mode_pkt_start_off[BLE_PHY_MODE_1M] = 40; /* 40 usecs */ g_ble_phy_data.phy_mode_pkt_start_off[BLE_PHY_MODE_2M] = 24; /* 24 usecs */ + g_ble_phy_data.phy_mode_pkt_start_off[BLE_PHY_MODE_CODED_125KBPS] = 376; /* 376 usecs */ + g_ble_phy_data.phy_mode_pkt_start_off[BLE_PHY_MODE_CODED_500KBPS] = 376; /* 376 usecs */ /* Default phy to use is 1M */ g_ble_phy_data.phy_cur_phy_mode = BLE_PHY_MODE_1M; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/24131d55/net/nimble/controller/src/ble_ll_conn.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_conn.c b/net/nimble/controller/src/ble_ll_conn.c index f6a7379..a7755ee 100644 --- a/net/nimble/controller/src/ble_ll_conn.c +++ b/net/nimble/controller/src/ble_ll_conn.c @@ -229,7 +229,9 @@ static inline int ble_ll_conn_phy_to_phy_mode(int phy, int phy_options) phy_mode = phy; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - /* XXX: TODO convert to coded phy mode if new phy is coded */ + if (phy == BLE_PHY_CODED && phy_options == BLE_HCI_LE_PHY_CODED_S8_PREF) { + phy_mode = BLE_PHY_MODE_CODED_125KBPS; + } #endif return phy_mode;
