You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by we...@apache.org on 2015/10/30 23:24:31 UTC

incubator-mynewt-larva git commit: Prefix ble stack modules, functions, definitions and variables with ble_

Repository: incubator-mynewt-larva
Updated Branches:
  refs/heads/master 36623dd5f -> 3b0f9ea8b


Prefix ble stack modules, functions, definitions and variables with ble_


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/commit/3b0f9ea8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/3b0f9ea8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/3b0f9ea8

Branch: refs/heads/master
Commit: 3b0f9ea8b273d0615a80a402e4e0829c430c1035
Parents: 36623dd
Author: Willam San Filippo <wi...@micosa.io>
Authored: Fri Oct 30 15:24:21 2015 -0700
Committer: Willam San Filippo <wi...@micosa.io>
Committed: Fri Oct 30 15:24:21 2015 -0700

----------------------------------------------------------------------
 .../controller/include/controller/ble_phy.h     | 109 ++++
 net/nimble/controller/include/controller/phy.h  | 109 ----
 net/nimble/controller/src/ble_phy.c             | 614 +++++++++++++++++++
 net/nimble/controller/src/phy.c                 | 614 -------------------
 4 files changed, 723 insertions(+), 723 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/3b0f9ea8/net/nimble/controller/include/controller/ble_phy.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_phy.h b/net/nimble/controller/include/controller/ble_phy.h
new file mode 100644
index 0000000..f527c44
--- /dev/null
+++ b/net/nimble/controller/include/controller/ble_phy.h
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2015 Stack Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef H_BLE_PHY_
+#define H_BLE_PHY_
+
+/* Forward declarations */
+struct os_mbuf;
+
+/* 
+ * XXX: Transceiver definitions. These dont belong here and will be moved
+ * once we finalize transceiver specific support.
+ */ 
+#define XCVR_RX_START_DELAY_USECS     (140)
+#define XCVR_TX_START_DELAY_USECS     (140)
+#define XCVR_PROC_DELAY_USECS         (50)
+#define XCVR_TX_SCHED_DELAY_USECS     \
+    (XCVR_TX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS)
+#define XCVR_RX_SCHED_DELAY_USECS     \
+    (XCVR_RX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS)
+
+/* Channel/Frequency defintions */
+#define BLE_PHY_NUM_CHANS           (40)
+#define BLE_PHY_NUM_DATA_CHANS      (37)
+#define BLE_PHY_CHAN0_FREQ_MHZ      (2402)
+#define BLE_PHY_DATA_CHAN0_FREQ_MHZ (2404)
+#define BLE_PHY_CHAN_SPACING_MHZ    (2)
+#define BLE_PHY_NUM_ADV_CHANS       (3)
+#define BLE_PHY_ADV_CHAN_START      (37)
+
+/* Power */
+#define BLE_PHY_MAX_PWR_DBM         (10)
+
+/* Deviation */
+#define BLE_PHY_DEV_KHZ             (185)
+#define BLE_PHY_BINARY_ZERO         (-BLE_PHY_DEV)
+#define BLE_PHY_BINARY_ONE          (BLE_PHY_DEV)
+
+/* Max. clock drift */
+#define BLE_PHY_MAX_DRIFT_PPM       (50)
+
+/* Data rate */
+#define BLE_PHY_BIT_RATE_BPS        (1000000)
+
+/* Macros */
+#define BLE_IS_ADV_CHAN(chan)       (chan >= BLE_PHY_ADV_CHAN_START)
+#define BLE_IS_DATA_CHAN(chan)      (chan < BLE_PHY_ADV_CHAN_START)
+
+/* PHY states */
+#define BLE_PHY_STATE_IDLE          (0)
+#define BLE_PHY_STATE_RX            (1)
+#define BLE_PHY_STATE_TX            (2)
+
+/* BLE PHY transitions */
+#define BLE_PHY_TRANSITION_NONE     (0)
+#define BLE_PHY_TRANSITION_RX_TX    (1)
+#define BLE_PHY_TRANSITION_TX_RX    (2)
+
+/* PHY error codes */
+#define BLE_PHY_ERR_RADIO_STATE     (1)
+#define BLE_PHY_ERR_INIT            (2)
+#define BLE_PHY_ERR_INV_PARAM       (3)
+#define BLE_PHY_ERR_NO_BUFS         (4)
+
+/* Initialize the PHY */
+int ble_phy_init(void);
+
+/* Reset the PHY */
+int ble_phy_reset(void);
+
+/* Set the PHY channel */
+int ble_phy_setchan(uint8_t chan);
+
+/* Place the PHY into transmit mode */
+int ble_phy_tx(struct os_mbuf *, uint8_t beg_trans, uint8_t end_trans);
+
+/* Place the PHY into receive mode */
+int ble_phy_rx(void);
+
+/* Get an RSSI reading */
+int ble_phy_rssi_get(void);
+
+/* Set the transmit power */
+int ble_phy_txpwr_set(int dbm);
+
+/* Get the transmit power */
+int ble_phy_txpwr_get(void);
+
+/* Disable the PHY */
+void ble_phy_disable(void);
+
+/* Gets the current state of the PHY */
+int ble_phy_state_get(void);
+
+
+#endif /* H_BLE_PHY_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/3b0f9ea8/net/nimble/controller/include/controller/phy.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/phy.h b/net/nimble/controller/include/controller/phy.h
deleted file mode 100644
index f527c44..0000000
--- a/net/nimble/controller/include/controller/phy.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/**
- * Copyright (c) 2015 Stack Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef H_BLE_PHY_
-#define H_BLE_PHY_
-
-/* Forward declarations */
-struct os_mbuf;
-
-/* 
- * XXX: Transceiver definitions. These dont belong here and will be moved
- * once we finalize transceiver specific support.
- */ 
-#define XCVR_RX_START_DELAY_USECS     (140)
-#define XCVR_TX_START_DELAY_USECS     (140)
-#define XCVR_PROC_DELAY_USECS         (50)
-#define XCVR_TX_SCHED_DELAY_USECS     \
-    (XCVR_TX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS)
-#define XCVR_RX_SCHED_DELAY_USECS     \
-    (XCVR_RX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS)
-
-/* Channel/Frequency defintions */
-#define BLE_PHY_NUM_CHANS           (40)
-#define BLE_PHY_NUM_DATA_CHANS      (37)
-#define BLE_PHY_CHAN0_FREQ_MHZ      (2402)
-#define BLE_PHY_DATA_CHAN0_FREQ_MHZ (2404)
-#define BLE_PHY_CHAN_SPACING_MHZ    (2)
-#define BLE_PHY_NUM_ADV_CHANS       (3)
-#define BLE_PHY_ADV_CHAN_START      (37)
-
-/* Power */
-#define BLE_PHY_MAX_PWR_DBM         (10)
-
-/* Deviation */
-#define BLE_PHY_DEV_KHZ             (185)
-#define BLE_PHY_BINARY_ZERO         (-BLE_PHY_DEV)
-#define BLE_PHY_BINARY_ONE          (BLE_PHY_DEV)
-
-/* Max. clock drift */
-#define BLE_PHY_MAX_DRIFT_PPM       (50)
-
-/* Data rate */
-#define BLE_PHY_BIT_RATE_BPS        (1000000)
-
-/* Macros */
-#define BLE_IS_ADV_CHAN(chan)       (chan >= BLE_PHY_ADV_CHAN_START)
-#define BLE_IS_DATA_CHAN(chan)      (chan < BLE_PHY_ADV_CHAN_START)
-
-/* PHY states */
-#define BLE_PHY_STATE_IDLE          (0)
-#define BLE_PHY_STATE_RX            (1)
-#define BLE_PHY_STATE_TX            (2)
-
-/* BLE PHY transitions */
-#define BLE_PHY_TRANSITION_NONE     (0)
-#define BLE_PHY_TRANSITION_RX_TX    (1)
-#define BLE_PHY_TRANSITION_TX_RX    (2)
-
-/* PHY error codes */
-#define BLE_PHY_ERR_RADIO_STATE     (1)
-#define BLE_PHY_ERR_INIT            (2)
-#define BLE_PHY_ERR_INV_PARAM       (3)
-#define BLE_PHY_ERR_NO_BUFS         (4)
-
-/* Initialize the PHY */
-int ble_phy_init(void);
-
-/* Reset the PHY */
-int ble_phy_reset(void);
-
-/* Set the PHY channel */
-int ble_phy_setchan(uint8_t chan);
-
-/* Place the PHY into transmit mode */
-int ble_phy_tx(struct os_mbuf *, uint8_t beg_trans, uint8_t end_trans);
-
-/* Place the PHY into receive mode */
-int ble_phy_rx(void);
-
-/* Get an RSSI reading */
-int ble_phy_rssi_get(void);
-
-/* Set the transmit power */
-int ble_phy_txpwr_set(int dbm);
-
-/* Get the transmit power */
-int ble_phy_txpwr_get(void);
-
-/* Disable the PHY */
-void ble_phy_disable(void);
-
-/* Gets the current state of the PHY */
-int ble_phy_state_get(void);
-
-
-#endif /* H_BLE_PHY_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/3b0f9ea8/net/nimble/controller/src/ble_phy.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_phy.c b/net/nimble/controller/src/ble_phy.c
new file mode 100644
index 0000000..3ed5a27
--- /dev/null
+++ b/net/nimble/controller/src/ble_phy.c
@@ -0,0 +1,614 @@
+/**
+ * Copyright (c) 2015 Stack Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <stdint.h>
+#include <assert.h>
+#include "os/os.h"
+#include "bsp/cmsis_nvic.h"
+#include "nimble/ble.h"
+#include "controller/ble_phy.h"
+#include "controller/ble_ll.h"
+#include "hal/hal_cputime.h"
+#include "mcu/nrf52.h"
+#include "mcu/nrf52_bitfields.h"
+
+/* To disable all radio interrupts */
+#define NRF52_RADIO_IRQ_MASK_ALL    (0x34FF)
+
+/* 
+ * We configure the nrf52 with a 1 byte S0 field, 8 bit length field, and
+ * zero bit S1 field. The preamble is 8 bits long.
+ */
+#define NRF52_LFLEN_BITS        (8)
+#define NRF52_S0_LEN            (1)
+
+/* Maximum length of frames */
+#define NRF52_MAXLEN            (255)
+#define NRF52_BALEN             (3)     /* For base address of 3 bytes */
+
+/* Maximum tx power */
+#define NRF52_TX_PWR_MAX_DBM    (4)
+#define NRF52_TX_PWR_MIN_DBM    (-40)
+
+/* BLE PHY data structure */
+struct ble_phy_obj
+{
+    int8_t  phy_txpwr_dbm;
+    uint8_t phy_chan;
+    uint8_t phy_state;
+    uint8_t phy_transition;
+    struct os_mbuf *rxpdu;
+};
+struct ble_phy_obj g_ble_phy_data;
+
+/* Statistics */
+struct ble_phy_statistics
+{
+    uint32_t tx_good;
+    uint32_t tx_fail;
+    uint32_t tx_bytes;
+    uint32_t rx_starts;
+    uint32_t rx_valid;
+    uint32_t rx_crc_err;
+    uint32_t phy_isrs;
+    uint32_t radio_state_errs;
+    uint32_t no_bufs;
+};
+
+struct ble_phy_statistics g_ble_phy_stats;
+
+/* XXX: TODO:
+ 
+ * 1) Test the following to make sure it works: suppose an event is already
+ * set to 1 and the interrupt is not enabled. What happens if you enable the
+ * interrupt with the event bit already set to 1  
+ */
+
+/**
+ * ble phy rxpdu get
+ *  
+ * Gets a mbuf for PDU reception. 
+ * 
+ * @return struct os_mbuf* Pointer to retrieved mbuf or NULL if none available
+ */
+static struct os_mbuf *
+ble_phy_rxpdu_get(void)
+{
+    struct os_mbuf *m;
+
+    m = g_ble_phy_data.rxpdu;
+    if (m == NULL) {
+        m = os_mbuf_get_pkthdr(&g_mbuf_pool);
+        if (!m) {
+            ++g_ble_phy_stats.no_bufs;
+        } else {
+            g_ble_phy_data.rxpdu = m;
+        }
+    }
+
+    return m;
+}
+
+static void
+nrf52_wait_disabled(void)
+{
+    uint32_t state;
+
+    state = NRF_RADIO->STATE;
+    if (state != RADIO_STATE_STATE_Disabled) {
+        if ((state == RADIO_STATE_STATE_RxDisable) ||
+            (state == RADIO_STATE_STATE_TxDisable)) {
+            /* This will end within a short time (6 usecs). Just poll */
+            while (NRF_RADIO->STATE == state) {
+                /* If this fails, something is really wrong. Should last
+                 * no more than 6 usecs */
+                /* XXX: should I have a way to bail out? */
+            }
+        }
+    }
+}
+
+static void
+ble_phy_isr(void)
+{
+    int rc;
+    uint8_t transition;
+    uint32_t irq_en;
+    uint32_t state;
+    uint32_t shortcuts;
+    struct os_mbuf *rxpdu;
+    struct ble_mbuf_hdr *ble_hdr;
+
+    /* Check for disabled event. This only happens for transmits now */
+    irq_en = NRF_RADIO->INTENCLR;
+    if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && NRF_RADIO->EVENTS_DISABLED) {
+        /* Better be in TX state! */
+        assert(g_ble_phy_data.phy_state == BLE_PHY_STATE_TX);
+
+        /* Clear events and clear interrupt on disabled event */
+        NRF_RADIO->EVENTS_DISABLED = 0;
+        NRF_RADIO->INTENCLR = RADIO_INTENCLR_DISABLED_Msk;
+        NRF_RADIO->EVENTS_END = 0;
+        shortcuts = NRF_RADIO->SHORTS;
+
+        transition = g_ble_phy_data.phy_transition;
+        if (transition == BLE_PHY_TRANSITION_TX_RX) {
+            /* XXX: for now, assume we receive on logical address 0 */
+            NRF_RADIO->RXADDRESSES = 1;
+
+            /* Debug check to make sure we go from tx to rx */
+            assert((shortcuts & RADIO_SHORTS_DISABLED_RXEN_Msk) != 0);
+
+            /* Packet pointer needs to be reset. */
+            if (g_ble_phy_data.rxpdu != NULL) {
+                NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+
+                /* I want to know when 1st byte received (after address) */
+                NRF_RADIO->BCC = 8; /* in bits */
+                NRF_RADIO->EVENTS_ADDRESS = 0;
+                NRF_RADIO->EVENTS_BCMATCH = 0;
+                NRF_RADIO->EVENTS_RSSIEND = 0;
+                NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk | 
+                                    RADIO_SHORTS_READY_START_Msk |
+                                    RADIO_SHORTS_ADDRESS_BCSTART_Msk |
+                                    RADIO_SHORTS_ADDRESS_RSSISTART_Msk |
+                                    RADIO_SHORTS_DISABLED_RSSISTOP_Msk;
+
+                NRF_RADIO->INTENSET = RADIO_INTENSET_ADDRESS_Msk;
+                g_ble_phy_data.phy_state = BLE_PHY_STATE_RX;
+            } else {
+                /* Disable the phy */
+                /* XXX: count no bufs? */
+                ble_phy_disable();
+            }
+        } else {
+            /* Better not be going from rx to tx! */
+            assert(transition == BLE_PHY_TRANSITION_NONE);
+        }
+    }
+
+    /* We get this if we have started to receive a frame */
+    if ((irq_en & RADIO_INTENCLR_ADDRESS_Msk) && NRF_RADIO->EVENTS_ADDRESS) {
+        /* Clear events and clear interrupt */
+        NRF_RADIO->EVENTS_ADDRESS = 0;
+        NRF_RADIO->INTENCLR = RADIO_INTENCLR_ADDRESS_Msk;
+
+        assert(g_ble_phy_data.rxpdu != NULL);
+
+        /* Wait to get 1st byte of frame */
+        while (1) {
+            state = NRF_RADIO->STATE;
+            if (NRF_RADIO->EVENTS_BCMATCH != 0) {
+                break;
+            }
+
+            /* 
+             * If state is disabled, we should have the BCMATCH. If not,
+             * something is wrong!
+             */ 
+            if (state == RADIO_STATE_STATE_Disabled) {
+                NRF_RADIO->INTENCLR = NRF52_RADIO_IRQ_MASK_ALL;
+                NRF_RADIO->SHORTS = 0;
+                goto phy_isr_exit;
+            }
+        }
+
+        /* Call Link Layer receive start function */
+        rc = ble_ll_rx_start(g_ble_phy_data.rxpdu);
+        if (rc >= 0) {
+            if (rc > 0) {
+                /* We need to go from disabled to TXEN */
+                NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk | 
+                                    RADIO_SHORTS_READY_START_Msk |
+                                    RADIO_SHORTS_DISABLED_TXEN_Msk;
+            } else {
+                NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk | 
+                                    RADIO_SHORTS_READY_START_Msk;
+            }
+
+            /* Set rx end ISR enable */
+            NRF_RADIO->INTENSET = RADIO_INTENSET_END_Msk;
+        } else {
+            /* Disable PHY */
+            ble_phy_disable();
+            irq_en = 0;
+        }
+
+        /* Count rx starts */
+        ++g_ble_phy_stats.rx_starts;
+    }
+
+    /* Receive packet end (we dont enable this for transmit) */
+    if ((irq_en & RADIO_INTENCLR_END_Msk) && NRF_RADIO->EVENTS_END) {
+        /* Clear events and clear interrupt */
+        NRF_RADIO->EVENTS_END = 0;
+        NRF_RADIO->INTENCLR = RADIO_INTENCLR_END_Msk;
+
+        /* Construct BLE header before handing up */
+        ble_hdr = BLE_MBUF_HDR_PTR(g_ble_phy_data.rxpdu);
+        ble_hdr->flags = 0;
+        assert(NRF_RADIO->EVENTS_RSSIEND != 0);
+        ble_hdr->rssi = -1 * NRF_RADIO->RSSISAMPLE;
+        ble_hdr->channel = g_ble_phy_data.phy_chan;
+        ble_hdr->crcok = (uint8_t)NRF_RADIO->CRCSTATUS;
+
+        /* Count PHY crc errors and valid packets */
+        if (ble_hdr->crcok == 0) {
+            ++g_ble_phy_stats.rx_crc_err;
+        } else {
+            ++g_ble_phy_stats.rx_valid;
+        }
+
+        /* Call Link Layer receive payload function */
+        rxpdu = g_ble_phy_data.rxpdu;
+        g_ble_phy_data.rxpdu = NULL;
+        rc = ble_ll_rx_end(rxpdu, ble_hdr->crcok);
+        if (rc < 0) {
+            /* Disable the PHY. */
+            ble_phy_disable();
+        }
+    }
+
+phy_isr_exit:
+    /* Ensures IRQ is cleared */
+    shortcuts = NRF_RADIO->SHORTS;
+
+    /* Count # of interrupts */
+    ++g_ble_phy_stats.phy_isrs;
+}
+
+/**
+ * ble phy init 
+ *  
+ * Initialize the PHY. This is expected to be called once. 
+ * 
+ * @return int 0: success; PHY error code otherwise
+ */
+int
+ble_phy_init(void)
+{
+    uint32_t os_tmo;
+
+    /* Make sure HFXO is started */
+    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
+    NRF_CLOCK->TASKS_HFCLKSTART = 1;
+    os_tmo = os_time_get() + (5 * (1000 / OS_TICKS_PER_SEC));
+    while (1) {
+        if (NRF_CLOCK->EVENTS_HFCLKSTARTED) {
+            break;
+        }
+        if ((int32_t)(os_time_get() - os_tmo) > 0) {
+            return BLE_PHY_ERR_INIT;
+        }
+    }
+
+    /* Set phy channel to an invalid channel so first set channel works */
+    g_ble_phy_data.phy_chan = BLE_PHY_NUM_CHANS;
+
+    /* Toggle peripheral power to reset (just in case) */
+    NRF_RADIO->POWER = 0;
+    NRF_RADIO->POWER = 1;
+
+    /* Disable all interrupts */
+    NRF_RADIO->INTENCLR = NRF52_RADIO_IRQ_MASK_ALL;
+
+    /* Set configuration registers */
+    NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_1Mbit;
+    NRF_RADIO->PCNF0 = (NRF52_LFLEN_BITS << RADIO_PCNF0_LFLEN_Pos) |
+                       (NRF52_S0_LEN << RADIO_PCNF0_S0LEN_Pos) |
+                       (RADIO_PCNF0_PLEN_8bit << RADIO_PCNF0_PLEN_Pos);
+    NRF_RADIO->PCNF1 = NRF52_MAXLEN | 
+                       (RADIO_PCNF1_ENDIAN_Little <<  RADIO_PCNF1_ENDIAN_Pos) |
+                       (NRF52_BALEN << RADIO_PCNF1_BALEN_Pos) |
+                       RADIO_PCNF1_WHITEEN_Msk;
+
+    /* Set base0 with the advertising access address */
+    NRF_RADIO->BASE0 = (BLE_ACCESS_ADDR_ADV << 8) & 0xFFFFFF00;
+    NRF_RADIO->PREFIX0 = (BLE_ACCESS_ADDR_ADV >> 24) & 0xFF;
+
+    /* Configure the CRC registers */
+    NRF_RADIO->CRCCNF = RADIO_CRCCNF_SKIPADDR_Msk | RADIO_CRCCNF_LEN_Three;
+
+    /* Configure BLE poly */
+    NRF_RADIO->CRCPOLY = 0x0100065B;
+
+    /* Configure IFS */
+    NRF_RADIO->TIFS = BLE_LL_IFS;
+
+    /* Set isr in vector table and enable interrupt */
+    NVIC_SetPriority(RADIO_IRQn, 0);
+    NVIC_SetVector(RADIO_IRQn, (uint32_t)ble_phy_isr);
+    NVIC_EnableIRQ(RADIO_IRQn);
+
+    return 0;
+}
+
+int 
+ble_phy_rx(void)
+{
+    /* Check radio state */
+    nrf52_wait_disabled();
+    if (NRF_RADIO->STATE != RADIO_STATE_STATE_Disabled) {
+        ble_phy_disable();
+        ++g_ble_phy_stats.radio_state_errs;
+        return BLE_PHY_ERR_RADIO_STATE;
+    }
+
+    /* If no pdu, get one */
+    if (ble_phy_rxpdu_get() == NULL) {
+        return BLE_PHY_ERR_NO_BUFS;
+    }
+
+    /* XXX: Assume that this is an advertising channel */
+    NRF_RADIO->CRCINIT = BLE_LL_CRCINIT_ADV;
+
+    /* XXX: for now, assume we receive on logical address 0 */
+    NRF_RADIO->RXADDRESSES = 1;
+
+    /* Set packet pointer */
+    NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+
+    /* Make sure all interrupts are disabled */
+    NRF_RADIO->INTENCLR = NRF52_RADIO_IRQ_MASK_ALL;
+
+    /* Clear events prior to enabling receive */
+    NRF_RADIO->EVENTS_END = 0;
+    NRF_RADIO->EVENTS_ADDRESS = 0;
+    NRF_RADIO->EVENTS_DISABLED = 0;
+    NRF_RADIO->EVENTS_BCMATCH = 0;
+    NRF_RADIO->EVENTS_RSSIEND = 0;
+
+    /* I want to know when 1st byte received (after address) */
+    NRF_RADIO->BCC = 8; /* in bits */
+    NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk | 
+                        RADIO_SHORTS_READY_START_Msk |
+                        RADIO_SHORTS_ADDRESS_BCSTART_Msk |
+                        RADIO_SHORTS_ADDRESS_RSSISTART_Msk |
+                        RADIO_SHORTS_DISABLED_RSSISTOP_Msk;
+
+    NRF_RADIO->INTENSET = RADIO_INTENSET_ADDRESS_Msk;
+
+    /* Start the receive task in the radio */
+    NRF_RADIO->TASKS_RXEN = 1;
+
+    g_ble_phy_data.phy_state = BLE_PHY_STATE_RX;
+
+    return 0;
+}
+
+int
+ble_phy_tx(struct os_mbuf *txpdu, uint8_t beg_trans, uint8_t end_trans)
+{
+    int rc;
+    uint32_t state;
+    uint32_t shortcuts;
+
+    /* Better have a pdu! */
+    assert(txpdu != NULL);
+
+    /* If radio is not disabled, */
+    nrf52_wait_disabled();
+
+    if (beg_trans == BLE_PHY_TRANSITION_RX_TX) {
+        if ((NRF_RADIO->SHORTS & RADIO_SHORTS_DISABLED_TXEN_Msk) == 0) {
+            assert(0);
+        }
+        /* Radio better be in TXRU state or we are in bad shape */
+        state = RADIO_STATE_STATE_TxRu;
+    } else {
+        /* Radio should be in disabled state */
+        state = RADIO_STATE_STATE_Disabled;
+    }
+
+    if (NRF_RADIO->STATE != state) {
+        ble_phy_disable();
+        ++g_ble_phy_stats.radio_state_errs;
+        return BLE_PHY_ERR_RADIO_STATE;
+    }
+
+    /* Select tx address */
+    if (g_ble_phy_data.phy_chan < BLE_PHY_NUM_DATA_CHANS) {
+        /* XXX: fix this */
+        assert(0);
+        NRF_RADIO->TXADDRESS = 0;
+        NRF_RADIO->RXADDRESSES = 0;
+        NRF_RADIO->CRCINIT = 0;
+    } else {
+        NRF_RADIO->TXADDRESS = 0;
+        NRF_RADIO->RXADDRESSES = 1;
+        NRF_RADIO->CRCINIT = BLE_LL_CRCINIT_ADV;
+    }
+
+    /* Set radio transmit data pointer */
+    NRF_RADIO->PACKETPTR = (uint32_t)txpdu->om_data;
+
+    /* Clear the ready, end and disabled events */
+    NRF_RADIO->EVENTS_READY = 0;
+    NRF_RADIO->EVENTS_END = 0;
+    NRF_RADIO->EVENTS_DISABLED = 0;
+
+    /* Enable shortcuts for transmit start/end. */
+    shortcuts = RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_READY_START_Msk;
+    if (end_trans == BLE_PHY_TRANSITION_TX_RX) {
+        /* If we are going into receive after this, try to get a buffer. */
+        if (ble_phy_rxpdu_get()) {
+            shortcuts |= RADIO_SHORTS_DISABLED_RXEN_Msk;
+        }
+        NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk;
+    }
+    NRF_RADIO->SHORTS = shortcuts;
+
+    /* Trigger transmit if our state was disabled */
+    if (state == RADIO_STATE_STATE_Disabled) {
+        NRF_RADIO->TASKS_TXEN = 1;
+    }
+
+    /* Set the PHY transition */
+    g_ble_phy_data.phy_transition = end_trans;
+
+    /* Read back radio state. If in TXRU, we are fine */
+    state = NRF_RADIO->STATE;
+    if ((state == RADIO_STATE_STATE_TxRu) || (state == RADIO_STATE_STATE_Tx)) {
+        /* Set phy state to transmitting and count packet statistics */
+        g_ble_phy_data.phy_state = BLE_PHY_STATE_TX;
+        ++g_ble_phy_stats.tx_good;
+        g_ble_phy_stats.tx_bytes += OS_MBUF_PKTHDR(txpdu)->omp_len;
+        rc = BLE_ERR_SUCCESS;
+    } else {
+        /* Frame failed to transmit */
+        ++g_ble_phy_stats.tx_fail;
+        ble_phy_disable();
+        rc = BLE_PHY_ERR_RADIO_STATE;
+    }
+
+    return rc;
+}
+
+/**
+ * ble phy txpwr set 
+ *  
+ * Set the transmit output power (in dBm). 
+ *  
+ * NOTE: If the output power specified is within the BLE limits but outside 
+ * the chip limits, we "rail" the power level so we dont exceed the min/max 
+ * chip values. 
+ * 
+ * @param dbm Power output in dBm.
+ * 
+ * @return int 0: success; anything else is an error
+ */
+int
+ble_phy_txpwr_set(int dbm)
+{
+    /* Check valid range */
+    assert(dbm <= BLE_PHY_MAX_PWR_DBM);
+
+    /* "Rail" power level if outside supported range */
+    if (dbm > NRF52_TX_PWR_MAX_DBM) {
+        dbm = NRF52_TX_PWR_MAX_DBM;
+    } else {
+        if (dbm < NRF52_TX_PWR_MIN_DBM) {
+            dbm = NRF52_TX_PWR_MIN_DBM;
+        }
+    }
+
+    NRF_RADIO->TXPOWER = dbm;
+    g_ble_phy_data.phy_txpwr_dbm = dbm;
+
+    return 0;
+}
+
+/**
+ * ble phy txpwr get
+ *  
+ * Get the transmit power. 
+ * 
+ * @return int  The current PHY transmit power, in dBm
+ */
+int
+ble_phy_txpwr_get(void)
+{
+    return g_ble_phy_data.phy_txpwr_dbm;
+}
+
+/**
+ * ble phy setchan 
+ *  
+ * Sets the logical frequency of the transceiver. The input parameter is the 
+ * BLE channel index (0 to 39, inclusive). The NRF52 frequency register 
+ * works like this: logical frequency = 2400 + FREQ (MHz). 
+ *  
+ * Thus, to get a logical frequency of 2402 MHz, you would program the 
+ * FREQUENCY register to 2. 
+ * 
+ * @param chan This is the Data Channel Index or Advertising Channel index
+ * 
+ * @return int 0: success; PHY error code otherwise
+ */
+int
+ble_phy_setchan(uint8_t chan)
+{
+    uint8_t freq;
+
+    assert(chan < BLE_PHY_NUM_CHANS);
+
+    /* Check for valid channel range */
+    if (chan >= BLE_PHY_NUM_CHANS) {
+        return BLE_PHY_ERR_INV_PARAM;
+    }
+
+    /* If the current channel is set, just return */
+    if (g_ble_phy_data.phy_chan == chan) {
+        return 0;
+    }
+
+    /* Get correct nrf52 frequency */
+    if (chan < BLE_PHY_NUM_DATA_CHANS) {
+        if (chan < 11) {
+            /* Data channel 0 starts at 2404. 0 - 10 are contiguous */
+            freq = (BLE_PHY_DATA_CHAN0_FREQ_MHZ - 2400) + 
+                   (BLE_PHY_CHAN_SPACING_MHZ * chan);
+        } else {
+            /* Data channel 11 starts at 2428. 0 - 10 are contiguous */
+            freq = (BLE_PHY_DATA_CHAN0_FREQ_MHZ - 2400) + 
+                   (BLE_PHY_CHAN_SPACING_MHZ * (chan + 1));
+        }
+    } else {
+        if (chan == 37) {
+            freq = BLE_PHY_CHAN_SPACING_MHZ;
+        } else if (chan == 38) {
+            /* This advertising channel is at 2426 MHz */
+            freq = BLE_PHY_CHAN_SPACING_MHZ * 13;
+        } else {
+            /* This advertising channel is at 2480 MHz */
+            freq = BLE_PHY_CHAN_SPACING_MHZ * 40;
+        }
+    }
+
+    /* Set the frequency and the data whitening initial value */
+    g_ble_phy_data.phy_chan = chan;
+    NRF_RADIO->FREQUENCY = freq;
+    NRF_RADIO->DATAWHITEIV = chan;
+
+    return 0;
+}
+
+/**
+ * Disable the PHY. This will do the following: 
+ *  -> Turn off all phy interrupts.
+ *  -> Disable internal shortcuts.
+ *  -> Disable the radio.
+ *  -> Sets phy state to idle.
+ */
+void
+ble_phy_disable(void)
+{
+    NRF_RADIO->INTENCLR = NRF52_RADIO_IRQ_MASK_ALL;
+    NRF_RADIO->SHORTS = 0;
+    NRF_RADIO->TASKS_DISABLE = 1;
+    g_ble_phy_data.phy_state = BLE_PHY_STATE_IDLE;
+}
+
+/**
+ * Return the phy state
+ * 
+ * @return int The current PHY state.
+ */
+int 
+ble_phy_state_get(void)
+{
+    return g_ble_phy_data.phy_state;
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/3b0f9ea8/net/nimble/controller/src/phy.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/phy.c b/net/nimble/controller/src/phy.c
deleted file mode 100644
index f987ba6..0000000
--- a/net/nimble/controller/src/phy.c
+++ /dev/null
@@ -1,614 +0,0 @@
-/**
- * Copyright (c) 2015 Stack Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <stdint.h>
-#include <assert.h>
-#include "os/os.h"
-#include "bsp/cmsis_nvic.h"
-#include "nimble/ble.h"
-#include "controller/phy.h"
-#include "controller/ble_ll.h"
-#include "hal/hal_cputime.h"
-#include "mcu/nrf52.h"
-#include "mcu/nrf52_bitfields.h"
-
-/* To disable all radio interrupts */
-#define NRF52_RADIO_IRQ_MASK_ALL    (0x34FF)
-
-/* 
- * We configure the nrf52 with a 1 byte S0 field, 8 bit length field, and
- * zero bit S1 field. The preamble is 8 bits long.
- */
-#define NRF52_LFLEN_BITS        (8)
-#define NRF52_S0_LEN            (1)
-
-/* Maximum length of frames */
-#define NRF52_MAXLEN            (255)
-#define NRF52_BALEN             (3)     /* For base address of 3 bytes */
-
-/* Maximum tx power */
-#define NRF52_TX_PWR_MAX_DBM    (4)
-#define NRF52_TX_PWR_MIN_DBM    (-40)
-
-/* BLE PHY data structure */
-struct ble_phy_obj
-{
-    int8_t  phy_txpwr_dbm;
-    uint8_t phy_chan;
-    uint8_t phy_state;
-    uint8_t phy_transition;
-    struct os_mbuf *rxpdu;
-};
-struct ble_phy_obj g_ble_phy_data;
-
-/* Statistics */
-struct ble_phy_statistics
-{
-    uint32_t tx_good;
-    uint32_t tx_fail;
-    uint32_t tx_bytes;
-    uint32_t rx_starts;
-    uint32_t rx_valid;
-    uint32_t rx_crc_err;
-    uint32_t phy_isrs;
-    uint32_t radio_state_errs;
-    uint32_t no_bufs;
-};
-
-struct ble_phy_statistics g_ble_phy_stats;
-
-/* XXX: TODO:
- 
- * 1) Test the following to make sure it works: suppose an event is already
- * set to 1 and the interrupt is not enabled. What happens if you enable the
- * interrupt with the event bit already set to 1  
- */
-
-/**
- * ble phy rxpdu get
- *  
- * Gets a mbuf for PDU reception. 
- * 
- * @return struct os_mbuf* Pointer to retrieved mbuf or NULL if none available
- */
-static struct os_mbuf *
-ble_phy_rxpdu_get(void)
-{
-    struct os_mbuf *m;
-
-    m = g_ble_phy_data.rxpdu;
-    if (m == NULL) {
-        m = os_mbuf_get_pkthdr(&g_mbuf_pool);
-        if (!m) {
-            ++g_ble_phy_stats.no_bufs;
-        } else {
-            g_ble_phy_data.rxpdu = m;
-        }
-    }
-
-    return m;
-}
-
-static void
-nrf52_wait_disabled(void)
-{
-    uint32_t state;
-
-    state = NRF_RADIO->STATE;
-    if (state != RADIO_STATE_STATE_Disabled) {
-        if ((state == RADIO_STATE_STATE_RxDisable) ||
-            (state == RADIO_STATE_STATE_TxDisable)) {
-            /* This will end within a short time (6 usecs). Just poll */
-            while (NRF_RADIO->STATE == state) {
-                /* If this fails, something is really wrong. Should last
-                 * no more than 6 usecs */
-                /* XXX: should I have a way to bail out? */
-            }
-        }
-    }
-}
-
-static void
-ble_phy_isr(void)
-{
-    int rc;
-    uint8_t transition;
-    uint32_t irq_en;
-    uint32_t state;
-    uint32_t shortcuts;
-    struct os_mbuf *rxpdu;
-    struct ble_mbuf_hdr *ble_hdr;
-
-    /* Check for disabled event. This only happens for transmits now */
-    irq_en = NRF_RADIO->INTENCLR;
-    if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && NRF_RADIO->EVENTS_DISABLED) {
-        /* Better be in TX state! */
-        assert(g_ble_phy_data.phy_state == BLE_PHY_STATE_TX);
-
-        /* Clear events and clear interrupt on disabled event */
-        NRF_RADIO->EVENTS_DISABLED = 0;
-        NRF_RADIO->INTENCLR = RADIO_INTENCLR_DISABLED_Msk;
-        NRF_RADIO->EVENTS_END = 0;
-        shortcuts = NRF_RADIO->SHORTS;
-
-        transition = g_ble_phy_data.phy_transition;
-        if (transition == BLE_PHY_TRANSITION_TX_RX) {
-            /* XXX: for now, assume we receive on logical address 0 */
-            NRF_RADIO->RXADDRESSES = 1;
-
-            /* Debug check to make sure we go from tx to rx */
-            assert((shortcuts & RADIO_SHORTS_DISABLED_RXEN_Msk) != 0);
-
-            /* Packet pointer needs to be reset. */
-            if (g_ble_phy_data.rxpdu != NULL) {
-                NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
-
-                /* I want to know when 1st byte received (after address) */
-                NRF_RADIO->BCC = 8; /* in bits */
-                NRF_RADIO->EVENTS_ADDRESS = 0;
-                NRF_RADIO->EVENTS_BCMATCH = 0;
-                NRF_RADIO->EVENTS_RSSIEND = 0;
-                NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk | 
-                                    RADIO_SHORTS_READY_START_Msk |
-                                    RADIO_SHORTS_ADDRESS_BCSTART_Msk |
-                                    RADIO_SHORTS_ADDRESS_RSSISTART_Msk |
-                                    RADIO_SHORTS_DISABLED_RSSISTOP_Msk;
-
-                NRF_RADIO->INTENSET = RADIO_INTENSET_ADDRESS_Msk;
-                g_ble_phy_data.phy_state = BLE_PHY_STATE_RX;
-            } else {
-                /* Disable the phy */
-                /* XXX: count no bufs? */
-                ble_phy_disable();
-            }
-        } else {
-            /* Better not be going from rx to tx! */
-            assert(transition == BLE_PHY_TRANSITION_NONE);
-        }
-    }
-
-    /* We get this if we have started to receive a frame */
-    if ((irq_en & RADIO_INTENCLR_ADDRESS_Msk) && NRF_RADIO->EVENTS_ADDRESS) {
-        /* Clear events and clear interrupt */
-        NRF_RADIO->EVENTS_ADDRESS = 0;
-        NRF_RADIO->INTENCLR = RADIO_INTENCLR_ADDRESS_Msk;
-
-        assert(g_ble_phy_data.rxpdu != NULL);
-
-        /* Wait to get 1st byte of frame */
-        while (1) {
-            state = NRF_RADIO->STATE;
-            if (NRF_RADIO->EVENTS_BCMATCH != 0) {
-                break;
-            }
-
-            /* 
-             * If state is disabled, we should have the BCMATCH. If not,
-             * something is wrong!
-             */ 
-            if (state == RADIO_STATE_STATE_Disabled) {
-                NRF_RADIO->INTENCLR = NRF52_RADIO_IRQ_MASK_ALL;
-                NRF_RADIO->SHORTS = 0;
-                goto phy_isr_exit;
-            }
-        }
-
-        /* Call Link Layer receive start function */
-        rc = ble_ll_rx_start(g_ble_phy_data.rxpdu);
-        if (rc >= 0) {
-            if (rc > 0) {
-                /* We need to go from disabled to TXEN */
-                NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk | 
-                                    RADIO_SHORTS_READY_START_Msk |
-                                    RADIO_SHORTS_DISABLED_TXEN_Msk;
-            } else {
-                NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk | 
-                                    RADIO_SHORTS_READY_START_Msk;
-            }
-
-            /* Set rx end ISR enable */
-            NRF_RADIO->INTENSET = RADIO_INTENSET_END_Msk;
-        } else {
-            /* Disable PHY */
-            ble_phy_disable();
-            irq_en = 0;
-        }
-
-        /* Count rx starts */
-        ++g_ble_phy_stats.rx_starts;
-    }
-
-    /* Receive packet end (we dont enable this for transmit) */
-    if ((irq_en & RADIO_INTENCLR_END_Msk) && NRF_RADIO->EVENTS_END) {
-        /* Clear events and clear interrupt */
-        NRF_RADIO->EVENTS_END = 0;
-        NRF_RADIO->INTENCLR = RADIO_INTENCLR_END_Msk;
-
-        /* Construct BLE header before handing up */
-        ble_hdr = BLE_MBUF_HDR_PTR(g_ble_phy_data.rxpdu);
-        ble_hdr->flags = 0;
-        assert(NRF_RADIO->EVENTS_RSSIEND != 0);
-        ble_hdr->rssi = -1 * NRF_RADIO->RSSISAMPLE;
-        ble_hdr->channel = g_ble_phy_data.phy_chan;
-        ble_hdr->crcok = (uint8_t)NRF_RADIO->CRCSTATUS;
-
-        /* Count PHY crc errors and valid packets */
-        if (ble_hdr->crcok == 0) {
-            ++g_ble_phy_stats.rx_crc_err;
-        } else {
-            ++g_ble_phy_stats.rx_valid;
-        }
-
-        /* Call Link Layer receive payload function */
-        rxpdu = g_ble_phy_data.rxpdu;
-        g_ble_phy_data.rxpdu = NULL;
-        rc = ble_ll_rx_end(rxpdu, ble_hdr->crcok);
-        if (rc < 0) {
-            /* Disable the PHY. */
-            ble_phy_disable();
-        }
-    }
-
-phy_isr_exit:
-    /* Ensures IRQ is cleared */
-    shortcuts = NRF_RADIO->SHORTS;
-
-    /* Count # of interrupts */
-    ++g_ble_phy_stats.phy_isrs;
-}
-
-/**
- * ble phy init 
- *  
- * Initialize the PHY. This is expected to be called once. 
- * 
- * @return int 0: success; PHY error code otherwise
- */
-int
-ble_phy_init(void)
-{
-    uint32_t os_tmo;
-
-    /* Make sure HFXO is started */
-    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
-    NRF_CLOCK->TASKS_HFCLKSTART = 1;
-    os_tmo = os_time_get() + (5 * (1000 / OS_TICKS_PER_SEC));
-    while (1) {
-        if (NRF_CLOCK->EVENTS_HFCLKSTARTED) {
-            break;
-        }
-        if ((int32_t)(os_time_get() - os_tmo) > 0) {
-            return BLE_PHY_ERR_INIT;
-        }
-    }
-
-    /* Set phy channel to an invalid channel so first set channel works */
-    g_ble_phy_data.phy_chan = BLE_PHY_NUM_CHANS;
-
-    /* Toggle peripheral power to reset (just in case) */
-    NRF_RADIO->POWER = 0;
-    NRF_RADIO->POWER = 1;
-
-    /* Disable all interrupts */
-    NRF_RADIO->INTENCLR = NRF52_RADIO_IRQ_MASK_ALL;
-
-    /* Set configuration registers */
-    NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_1Mbit;
-    NRF_RADIO->PCNF0 = (NRF52_LFLEN_BITS << RADIO_PCNF0_LFLEN_Pos) |
-                       (NRF52_S0_LEN << RADIO_PCNF0_S0LEN_Pos) |
-                       (RADIO_PCNF0_PLEN_8bit << RADIO_PCNF0_PLEN_Pos);
-    NRF_RADIO->PCNF1 = NRF52_MAXLEN | 
-                       (RADIO_PCNF1_ENDIAN_Little <<  RADIO_PCNF1_ENDIAN_Pos) |
-                       (NRF52_BALEN << RADIO_PCNF1_BALEN_Pos) |
-                       RADIO_PCNF1_WHITEEN_Msk;
-
-    /* Set base0 with the advertising access address */
-    NRF_RADIO->BASE0 = (BLE_ACCESS_ADDR_ADV << 8) & 0xFFFFFF00;
-    NRF_RADIO->PREFIX0 = (BLE_ACCESS_ADDR_ADV >> 24) & 0xFF;
-
-    /* Configure the CRC registers */
-    NRF_RADIO->CRCCNF = RADIO_CRCCNF_SKIPADDR_Msk | RADIO_CRCCNF_LEN_Three;
-
-    /* Configure BLE poly */
-    NRF_RADIO->CRCPOLY = 0x0100065B;
-
-    /* Configure IFS */
-    NRF_RADIO->TIFS = BLE_LL_IFS;
-
-    /* Set isr in vector table and enable interrupt */
-    NVIC_SetPriority(RADIO_IRQn, 0);
-    NVIC_SetVector(RADIO_IRQn, (uint32_t)ble_phy_isr);
-    NVIC_EnableIRQ(RADIO_IRQn);
-
-    return 0;
-}
-
-int 
-ble_phy_rx(void)
-{
-    /* Check radio state */
-    nrf52_wait_disabled();
-    if (NRF_RADIO->STATE != RADIO_STATE_STATE_Disabled) {
-        ble_phy_disable();
-        ++g_ble_phy_stats.radio_state_errs;
-        return BLE_PHY_ERR_RADIO_STATE;
-    }
-
-    /* If no pdu, get one */
-    if (ble_phy_rxpdu_get() == NULL) {
-        return BLE_PHY_ERR_NO_BUFS;
-    }
-
-    /* XXX: Assume that this is an advertising channel */
-    NRF_RADIO->CRCINIT = BLE_LL_CRCINIT_ADV;
-
-    /* XXX: for now, assume we receive on logical address 0 */
-    NRF_RADIO->RXADDRESSES = 1;
-
-    /* Set packet pointer */
-    NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
-
-    /* Make sure all interrupts are disabled */
-    NRF_RADIO->INTENCLR = NRF52_RADIO_IRQ_MASK_ALL;
-
-    /* Clear events prior to enabling receive */
-    NRF_RADIO->EVENTS_END = 0;
-    NRF_RADIO->EVENTS_ADDRESS = 0;
-    NRF_RADIO->EVENTS_DISABLED = 0;
-    NRF_RADIO->EVENTS_BCMATCH = 0;
-    NRF_RADIO->EVENTS_RSSIEND = 0;
-
-    /* I want to know when 1st byte received (after address) */
-    NRF_RADIO->BCC = 8; /* in bits */
-    NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk | 
-                        RADIO_SHORTS_READY_START_Msk |
-                        RADIO_SHORTS_ADDRESS_BCSTART_Msk |
-                        RADIO_SHORTS_ADDRESS_RSSISTART_Msk |
-                        RADIO_SHORTS_DISABLED_RSSISTOP_Msk;
-
-    NRF_RADIO->INTENSET = RADIO_INTENSET_ADDRESS_Msk;
-
-    /* Start the receive task in the radio */
-    NRF_RADIO->TASKS_RXEN = 1;
-
-    g_ble_phy_data.phy_state = BLE_PHY_STATE_RX;
-
-    return 0;
-}
-
-int
-ble_phy_tx(struct os_mbuf *txpdu, uint8_t beg_trans, uint8_t end_trans)
-{
-    int rc;
-    uint32_t state;
-    uint32_t shortcuts;
-
-    /* Better have a pdu! */
-    assert(txpdu != NULL);
-
-    /* If radio is not disabled, */
-    nrf52_wait_disabled();
-
-    if (beg_trans == BLE_PHY_TRANSITION_RX_TX) {
-        if ((NRF_RADIO->SHORTS & RADIO_SHORTS_DISABLED_TXEN_Msk) == 0) {
-            assert(0);
-        }
-        /* Radio better be in TXRU state or we are in bad shape */
-        state = RADIO_STATE_STATE_TxRu;
-    } else {
-        /* Radio should be in disabled state */
-        state = RADIO_STATE_STATE_Disabled;
-    }
-
-    if (NRF_RADIO->STATE != state) {
-        ble_phy_disable();
-        ++g_ble_phy_stats.radio_state_errs;
-        return BLE_PHY_ERR_RADIO_STATE;
-    }
-
-    /* Select tx address */
-    if (g_ble_phy_data.phy_chan < BLE_PHY_NUM_DATA_CHANS) {
-        /* XXX: fix this */
-        assert(0);
-        NRF_RADIO->TXADDRESS = 0;
-        NRF_RADIO->RXADDRESSES = 0;
-        NRF_RADIO->CRCINIT = 0;
-    } else {
-        NRF_RADIO->TXADDRESS = 0;
-        NRF_RADIO->RXADDRESSES = 1;
-        NRF_RADIO->CRCINIT = BLE_LL_CRCINIT_ADV;
-    }
-
-    /* Set radio transmit data pointer */
-    NRF_RADIO->PACKETPTR = (uint32_t)txpdu->om_data;
-
-    /* Clear the ready, end and disabled events */
-    NRF_RADIO->EVENTS_READY = 0;
-    NRF_RADIO->EVENTS_END = 0;
-    NRF_RADIO->EVENTS_DISABLED = 0;
-
-    /* Enable shortcuts for transmit start/end. */
-    shortcuts = RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_READY_START_Msk;
-    if (end_trans == BLE_PHY_TRANSITION_TX_RX) {
-        /* If we are going into receive after this, try to get a buffer. */
-        if (ble_phy_rxpdu_get()) {
-            shortcuts |= RADIO_SHORTS_DISABLED_RXEN_Msk;
-        }
-        NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk;
-    }
-    NRF_RADIO->SHORTS = shortcuts;
-
-    /* Trigger transmit if our state was disabled */
-    if (state == RADIO_STATE_STATE_Disabled) {
-        NRF_RADIO->TASKS_TXEN = 1;
-    }
-
-    /* Set the PHY transition */
-    g_ble_phy_data.phy_transition = end_trans;
-
-    /* Read back radio state. If in TXRU, we are fine */
-    state = NRF_RADIO->STATE;
-    if ((state == RADIO_STATE_STATE_TxRu) || (state == RADIO_STATE_STATE_Tx)) {
-        /* Set phy state to transmitting and count packet statistics */
-        g_ble_phy_data.phy_state = BLE_PHY_STATE_TX;
-        ++g_ble_phy_stats.tx_good;
-        g_ble_phy_stats.tx_bytes += OS_MBUF_PKTHDR(txpdu)->omp_len;
-        rc = BLE_ERR_SUCCESS;
-    } else {
-        /* Frame failed to transmit */
-        ++g_ble_phy_stats.tx_fail;
-        ble_phy_disable();
-        rc = BLE_PHY_ERR_RADIO_STATE;
-    }
-
-    return rc;
-}
-
-/**
- * ble phy txpwr set 
- *  
- * Set the transmit output power (in dBm). 
- *  
- * NOTE: If the output power specified is within the BLE limits but outside 
- * the chip limits, we "rail" the power level so we dont exceed the min/max 
- * chip values. 
- * 
- * @param dbm Power output in dBm.
- * 
- * @return int 0: success; anything else is an error
- */
-int
-ble_phy_txpwr_set(int dbm)
-{
-    /* Check valid range */
-    assert(dbm <= BLE_PHY_MAX_PWR_DBM);
-
-    /* "Rail" power level if outside supported range */
-    if (dbm > NRF52_TX_PWR_MAX_DBM) {
-        dbm = NRF52_TX_PWR_MAX_DBM;
-    } else {
-        if (dbm < NRF52_TX_PWR_MIN_DBM) {
-            dbm = NRF52_TX_PWR_MIN_DBM;
-        }
-    }
-
-    NRF_RADIO->TXPOWER = dbm;
-    g_ble_phy_data.phy_txpwr_dbm = dbm;
-
-    return 0;
-}
-
-/**
- * ble phy txpwr get
- *  
- * Get the transmit power. 
- * 
- * @return int  The current PHY transmit power, in dBm
- */
-int
-ble_phy_txpwr_get(void)
-{
-    return g_ble_phy_data.phy_txpwr_dbm;
-}
-
-/**
- * ble phy setchan 
- *  
- * Sets the logical frequency of the transceiver. The input parameter is the 
- * BLE channel index (0 to 39, inclusive). The NRF52 frequency register 
- * works like this: logical frequency = 2400 + FREQ (MHz). 
- *  
- * Thus, to get a logical frequency of 2402 MHz, you would program the 
- * FREQUENCY register to 2. 
- * 
- * @param chan This is the Data Channel Index or Advertising Channel index
- * 
- * @return int 0: success; PHY error code otherwise
- */
-int
-ble_phy_setchan(uint8_t chan)
-{
-    uint8_t freq;
-
-    assert(chan < BLE_PHY_NUM_CHANS);
-
-    /* Check for valid channel range */
-    if (chan >= BLE_PHY_NUM_CHANS) {
-        return BLE_PHY_ERR_INV_PARAM;
-    }
-
-    /* If the current channel is set, just return */
-    if (g_ble_phy_data.phy_chan == chan) {
-        return 0;
-    }
-
-    /* Get correct nrf52 frequency */
-    if (chan < BLE_PHY_NUM_DATA_CHANS) {
-        if (chan < 11) {
-            /* Data channel 0 starts at 2404. 0 - 10 are contiguous */
-            freq = (BLE_PHY_DATA_CHAN0_FREQ_MHZ - 2400) + 
-                   (BLE_PHY_CHAN_SPACING_MHZ * chan);
-        } else {
-            /* Data channel 11 starts at 2428. 0 - 10 are contiguous */
-            freq = (BLE_PHY_DATA_CHAN0_FREQ_MHZ - 2400) + 
-                   (BLE_PHY_CHAN_SPACING_MHZ * (chan + 1));
-        }
-    } else {
-        if (chan == 37) {
-            freq = BLE_PHY_CHAN_SPACING_MHZ;
-        } else if (chan == 38) {
-            /* This advertising channel is at 2426 MHz */
-            freq = BLE_PHY_CHAN_SPACING_MHZ * 13;
-        } else {
-            /* This advertising channel is at 2480 MHz */
-            freq = BLE_PHY_CHAN_SPACING_MHZ * 40;
-        }
-    }
-
-    /* Set the frequency and the data whitening initial value */
-    g_ble_phy_data.phy_chan = chan;
-    NRF_RADIO->FREQUENCY = freq;
-    NRF_RADIO->DATAWHITEIV = chan;
-
-    return 0;
-}
-
-/**
- * Disable the PHY. This will do the following: 
- *  -> Turn off all phy interrupts.
- *  -> Disable internal shortcuts.
- *  -> Disable the radio.
- *  -> Sets phy state to idle.
- */
-void
-ble_phy_disable(void)
-{
-    NRF_RADIO->INTENCLR = NRF52_RADIO_IRQ_MASK_ALL;
-    NRF_RADIO->SHORTS = 0;
-    NRF_RADIO->TASKS_DISABLE = 1;
-    g_ble_phy_data.phy_state = BLE_PHY_STATE_IDLE;
-}
-
-/**
- * Return the phy state
- * 
- * @return int The current PHY state.
- */
-int 
-ble_phy_state_get(void)
-{
-    return g_ble_phy_data.phy_state;
-}
-