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 2016/04/21 23:46:39 UTC
incubator-mynewt-core git commit: MYNEWT-284: fix nrf51 radio state
errors
Repository: incubator-mynewt-core
Updated Branches:
refs/heads/develop 88356a0df -> 27705013e
MYNEWT-284: fix nrf51 radio state errors
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/27705013
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/27705013
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/27705013
Branch: refs/heads/develop
Commit: 27705013e505dc6b90a7a946e7ce7f8e064ef0f4
Parents: 88356a0
Author: William San Filippo <wi...@runtime.io>
Authored: Thu Apr 21 14:46:17 2016 -0700
Committer: William San Filippo <wi...@runtime.io>
Committed: Thu Apr 21 14:46:24 2016 -0700
----------------------------------------------------------------------
net/nimble/drivers/nrf51/src/ble_phy.c | 272 +++++++++++++---------------
net/nimble/drivers/nrf52/src/ble_phy.c | 272 +++++++++++++---------------
2 files changed, 249 insertions(+), 295 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/27705013/net/nimble/drivers/nrf51/src/ble_phy.c
----------------------------------------------------------------------
diff --git a/net/nimble/drivers/nrf51/src/ble_phy.c b/net/nimble/drivers/nrf51/src/ble_phy.c
index bc4a258..d95329a 100644
--- a/net/nimble/drivers/nrf51/src/ble_phy.c
+++ b/net/nimble/drivers/nrf51/src/ble_phy.c
@@ -202,6 +202,11 @@ ble_phy_rxpdu_get(void)
return m;
}
+/**
+ * Called when we want to wait if the radio is in either the rx or tx
+ * disable states. We want to wait until that state is over before doing
+ * anything to the radio
+ */
static void
nrf_wait_disabled(void)
{
@@ -220,112 +225,135 @@ nrf_wait_disabled(void)
}
}
+/**
+ * Setup transceiver for receive.
+ */
static void
-ble_phy_isr(void)
+ble_phy_rx_xcvr_setup(void)
{
- int rc;
- uint8_t transition;
- uint8_t crcok;
- uint32_t irq_en;
- uint32_t state;
- uint32_t wfr_time;
#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
- uint8_t *dptr;
+ if (g_ble_phy_data.phy_encrypted) {
+ NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0];
+ NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
+ NRF_CCM->OUTPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+ NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
+ NRF_CCM->MODE = CCM_MODE_MODE_Decryption;
+ NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
+ NRF_CCM->SHORTS = 0;
+ NRF_CCM->EVENTS_ERROR = 0;
+ NRF_CCM->EVENTS_ENDCRYPT = 0;
+ NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk | PPI_CHEN_CH25_Msk;
+ } else {
+ NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+ }
+#else
+ NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
#endif
- struct os_mbuf *rxpdu;
- struct ble_mbuf_hdr *ble_hdr;
- /* Read irq register to determine which interrupts are enabled */
- irq_en = NRF_RADIO->INTENCLR;
+ /* Reset the rx started flag. Used for the wait for response */
+ g_ble_phy_data.phy_rx_started = 0;
+ g_ble_phy_data.phy_state = BLE_PHY_STATE_RX;
- /* Check for disabled event. This only happens for transmits now */
- 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);
+ /* I want to know when 1st byte received (after address) */
+ NRF_RADIO->BCC = 8; /* in bits */
+ NRF_RADIO->EVENTS_ADDRESS = 0;
+ NRF_RADIO->EVENTS_DEVMATCH = 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_DISABLED_TXEN_Msk |
+ RADIO_SHORTS_ADDRESS_BCSTART_Msk |
+ RADIO_SHORTS_ADDRESS_RSSISTART_Msk |
+ RADIO_SHORTS_DISABLED_RSSISTOP_Msk;
- ble_ll_log(BLE_LL_LOG_ID_PHY_TXEND, (g_ble_phy_txrx_buf[0] >> 8) & 0xFF,
- g_ble_phy_data.phy_encrypted, NRF_TIMER0->CC[2]);
+ NRF_RADIO->INTENSET = RADIO_INTENSET_ADDRESS_Msk;
+}
- /* 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;
- state = NRF_RADIO->SHORTS;
+/**
+ * Called from interrupt context when the transmit ends
+ *
+ */
+static void
+ble_phy_tx_end_isr(void)
+{
+ uint8_t transition;
+ uint32_t wfr_time;
+
+ /* Better be in TX state! */
+ assert(g_ble_phy_data.phy_state == BLE_PHY_STATE_TX);
+
+ /* Log the event */
+ ble_ll_log(BLE_LL_LOG_ID_PHY_TXEND, (g_ble_phy_txrx_buf[0] >> 8) & 0xFF,
+ g_ble_phy_data.phy_encrypted, NRF_TIMER0->CC[2]);
+
+ /* 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;
+ wfr_time = NRF_RADIO->SHORTS;
#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
- /*
- * XXX: not sure what to do. We had a HW error during transmission.
- * For now I just count a stat but continue on like all is good.
- */
- if (g_ble_phy_data.phy_encrypted) {
- if (NRF_CCM->EVENTS_ERROR) {
- STATS_INC(ble_phy_stats, tx_hw_err);
- NRF_CCM->EVENTS_ERROR = 0;
- }
+ /*
+ * XXX: not sure what to do. We had a HW error during transmission.
+ * For now I just count a stat but continue on like all is good.
+ */
+ if (g_ble_phy_data.phy_encrypted) {
+ if (NRF_CCM->EVENTS_ERROR) {
+ STATS_INC(ble_phy_stats, tx_hw_err);
+ NRF_CCM->EVENTS_ERROR = 0;
}
+ }
#endif
- transition = g_ble_phy_data.phy_transition;
- if (transition == BLE_PHY_TRANSITION_TX_RX) {
- /* Clear the rx started flag */
- g_ble_phy_data.phy_rx_started = 0;
+ transition = g_ble_phy_data.phy_transition;
+ if (transition == BLE_PHY_TRANSITION_TX_RX) {
+ /* Packet pointer needs to be reset. */
+ if (g_ble_phy_data.rxpdu != NULL) {
+ ble_phy_rx_xcvr_setup();
+ } else {
+ /* Disable the phy */
+ STATS_INC(ble_phy_stats, no_bufs);
+ ble_phy_disable();
+ }
+
+ /*
+ * Enable the wait for response timer. Note that cc #2 on
+ * timer 0 contains the transmit end time
+ */
+ wfr_time = NRF_TIMER0->CC[2];
+ wfr_time += cputime_usecs_to_ticks(BLE_LL_WFR_USECS);
+ ble_ll_wfr_enable(wfr_time);
+ } else {
+ /* Better not be going from rx to tx! */
+ assert(transition == BLE_PHY_TRANSITION_NONE);
+ }
+
+ /* Call transmit end callback */
+ if (g_ble_phy_data.txend_cb) {
+ g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg);
+ }
+}
- /* Packet pointer needs to be reset. */
- if (g_ble_phy_data.rxpdu != NULL) {
+static void
+ble_phy_isr(void)
+{
+ int rc;
+ uint8_t crcok;
+ uint32_t irq_en;
+ uint32_t state;
#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
- if (g_ble_phy_data.phy_encrypted) {
- NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0];
- NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
- NRF_CCM->OUTPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
- NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
- NRF_CCM->MODE = CCM_MODE_MODE_Decryption;
- NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
- NRF_CCM->SHORTS = 0;
- NRF_CCM->EVENTS_ENDCRYPT = 0;
- NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk | PPI_CHEN_CH25_Msk;
- } else {
- NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
- }
-#else
- NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+ uint8_t *dptr;
#endif
+ struct os_mbuf *rxpdu;
+ struct ble_mbuf_hdr *ble_hdr;
- /* I want to know when 1st byte received (after address) */
- NRF_RADIO->BCC = 8; /* in bits */
- NRF_RADIO->EVENTS_ADDRESS = 0;
- NRF_RADIO->EVENTS_DEVMATCH = 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 */
- STATS_INC(ble_phy_stats, no_bufs);
- ble_phy_disable();
- }
-
- /*
- * Enable the wait for response timer. Note that cc #2 on
- * timer 0 contains the transmit end time
- */
- wfr_time = NRF_TIMER0->CC[2];
- wfr_time += cputime_usecs_to_ticks(BLE_LL_WFR_USECS);
- ble_ll_wfr_enable(wfr_time);
- } else {
- /* Better not be going from rx to tx! */
- assert(transition == BLE_PHY_TRANSITION_NONE);
- }
+ /* Read irq register to determine which interrupts are enabled */
+ irq_en = NRF_RADIO->INTENCLR;
- /* Call transmit end callback */
- if (g_ble_phy_data.txend_cb) {
- g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg);
- }
+ /* Check for disabled event. This only happens for transmits now */
+ if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && NRF_RADIO->EVENTS_DISABLED) {
+ ble_phy_tx_end_isr();
}
/* We get this if we have started to receive a frame */
@@ -363,18 +391,8 @@ ble_phy_isr(void)
/* Call Link Layer receive start function */
rc = ble_ll_rx_start(g_ble_phy_data.rxpdu, g_ble_phy_data.phy_chan);
if (rc >= 0) {
+ /* Set rx started flag and enable rx end ISR */
g_ble_phy_data.phy_rx_started = 1;
- 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 */
@@ -457,7 +475,6 @@ ble_phy_isr(void)
#endif
rc = ble_ll_rx_end(rxpdu, ble_hdr);
if (rc < 0) {
- /* Disable the PHY. */
ble_phy_disable();
}
}
@@ -563,6 +580,11 @@ ble_phy_init(void)
return 0;
}
+/**
+ * Puts the phy into receive mode.
+ *
+ * @return int 0: success; BLE Phy error code otherwise
+ */
int
ble_phy_rx(void)
{
@@ -579,64 +601,19 @@ ble_phy_rx(void)
return BLE_PHY_ERR_NO_BUFS;
}
- /* Set packet pointer */
-#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
- if (g_ble_phy_data.phy_encrypted) {
- NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0];
- } else {
- NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
- }
-#else
- NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
-#endif
-
/* Make sure all interrupts are disabled */
NRF_RADIO->INTENCLR = NRF_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;
- NRF_RADIO->EVENTS_DEVMATCH = 0;
-
-#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
- if (g_ble_phy_data.phy_encrypted) {
- NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
- NRF_CCM->OUTPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
- NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
- NRF_CCM->EVENTS_ERROR = 0;
- NRF_CCM->EVENTS_ENDCRYPT = 0;
- NRF_CCM->MODE = CCM_MODE_MODE_Decryption;
- /* XXX: can I just set this once? (i.e per connection)? In other
- words, only do this during encrypt enable? */
- NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
- NRF_CCM->SHORTS = 0;
- NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk | PPI_CHEN_CH25_Msk;
- }
-#endif
- /* XXX: could it be that I am late turning on the device? That I need
- to automatically go from rx to tx always? I dont here */
- /* 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;
-
- /* Reset the rx started flag. Used for the wait for response */
- g_ble_phy_data.phy_rx_started = 0;
+ /* Setup for rx */
+ ble_phy_rx_xcvr_setup();
/* Start the receive task in the radio */
NRF_RADIO->TASKS_RXEN = 1;
- g_ble_phy_data.phy_state = BLE_PHY_STATE_RX;
-
return 0;
}
@@ -998,4 +975,3 @@ ble_phy_rx_started(void)
{
return g_ble_phy_data.phy_rx_started;
}
-
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/27705013/net/nimble/drivers/nrf52/src/ble_phy.c
----------------------------------------------------------------------
diff --git a/net/nimble/drivers/nrf52/src/ble_phy.c b/net/nimble/drivers/nrf52/src/ble_phy.c
index fee6043..cecbe60 100644
--- a/net/nimble/drivers/nrf52/src/ble_phy.c
+++ b/net/nimble/drivers/nrf52/src/ble_phy.c
@@ -196,6 +196,11 @@ ble_phy_rxpdu_get(void)
return m;
}
+/**
+ * Called when we want to wait if the radio is in either the rx or tx
+ * disable states. We want to wait until that state is over before doing
+ * anything to the radio
+ */
static void
nrf_wait_disabled(void)
{
@@ -214,110 +219,134 @@ nrf_wait_disabled(void)
}
}
+/**
+ * Setup transceiver for receive
+ *
+ */
static void
-ble_phy_isr(void)
+ble_phy_rx_xcvr_setup(void)
+{
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+ if (g_ble_phy_data.phy_encrypted) {
+ NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0];
+ NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
+ NRF_CCM->OUTPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+ NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
+ NRF_CCM->MODE = CCM_MODE_LENGTH_Msk | CCM_MODE_MODE_Decryption;
+ NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
+ NRF_CCM->SHORTS = 0;
+ NRF_CCM->EVENTS_ERROR = 0;
+ NRF_CCM->EVENTS_ENDCRYPT = 0;
+ NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk | PPI_CHEN_CH25_Msk;
+ } else {
+ NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+ }
+#else
+ NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+#endif
+
+ /* Reset the rx started flag. Used for the wait for response */
+ g_ble_phy_data.phy_rx_started = 0;
+ g_ble_phy_data.phy_state = BLE_PHY_STATE_RX;
+
+ /* I want to know when 1st byte received (after address) */
+ NRF_RADIO->BCC = 8; /* in bits */
+ NRF_RADIO->EVENTS_ADDRESS = 0;
+ NRF_RADIO->EVENTS_DEVMATCH = 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_DISABLED_TXEN_Msk |
+ RADIO_SHORTS_ADDRESS_BCSTART_Msk |
+ RADIO_SHORTS_ADDRESS_RSSISTART_Msk |
+ RADIO_SHORTS_DISABLED_RSSISTOP_Msk;
+
+ NRF_RADIO->INTENSET = RADIO_INTENSET_ADDRESS_Msk;
+}
+
+/**
+ * Called from interrupt context when the transmit ends
+ *
+ */
+static void
+ble_phy_tx_end_isr(void)
{
- int rc;
uint8_t transition;
- uint8_t crcok;
- uint32_t irq_en;
- uint32_t state;
uint32_t wfr_time;
- uint8_t *dptr;
- struct os_mbuf *rxpdu;
- struct ble_mbuf_hdr *ble_hdr;
-
- /* Read irq register to determine which interrupts are enabled */
- irq_en = NRF_RADIO->INTENCLR;
- /* Check for disabled event. This only happens for transmits now */
- 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);
+ /* Better be in TX state! */
+ assert(g_ble_phy_data.phy_state == BLE_PHY_STATE_TX);
- ble_ll_log(BLE_LL_LOG_ID_PHY_TXEND, (g_ble_phy_txrx_buf[0] >> 8) & 0xFF,
- g_ble_phy_data.phy_encrypted, NRF_TIMER0->CC[2]);
+ /* Log the event */
+ ble_ll_log(BLE_LL_LOG_ID_PHY_TXEND, (g_ble_phy_txrx_buf[0] >> 8) & 0xFF,
+ g_ble_phy_data.phy_encrypted, NRF_TIMER0->CC[2]);
- /* 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;
- state = NRF_RADIO->SHORTS;
+ /* 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;
+ wfr_time = NRF_RADIO->SHORTS;
#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
- /*
- * XXX: not sure what to do. We had a HW error during transmission.
- * For now I just count a stat but continue on like all is good.
- */
- if (g_ble_phy_data.phy_encrypted) {
- if (NRF_CCM->EVENTS_ERROR) {
- STATS_INC(ble_phy_stats, tx_hw_err);
- NRF_CCM->EVENTS_ERROR = 0;
- }
+ /*
+ * XXX: not sure what to do. We had a HW error during transmission.
+ * For now I just count a stat but continue on like all is good.
+ */
+ if (g_ble_phy_data.phy_encrypted) {
+ if (NRF_CCM->EVENTS_ERROR) {
+ STATS_INC(ble_phy_stats, tx_hw_err);
+ NRF_CCM->EVENTS_ERROR = 0;
}
+ }
#endif
- transition = g_ble_phy_data.phy_transition;
- if (transition == BLE_PHY_TRANSITION_TX_RX) {
- /* Clear the rx started flag */
- g_ble_phy_data.phy_rx_started = 0;
+ transition = g_ble_phy_data.phy_transition;
+ if (transition == BLE_PHY_TRANSITION_TX_RX) {
+ /* Packet pointer needs to be reset. */
+ if (g_ble_phy_data.rxpdu != NULL) {
+ ble_phy_rx_xcvr_setup();
+ } else {
+ /* Disable the phy */
+ STATS_INC(ble_phy_stats, no_bufs);
+ ble_phy_disable();
+ }
- /* Packet pointer needs to be reset. */
- if (g_ble_phy_data.rxpdu != NULL) {
-#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
- if (g_ble_phy_data.phy_encrypted) {
- NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0];
- NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
- NRF_CCM->OUTPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
- NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
- NRF_CCM->MODE = CCM_MODE_LENGTH_Msk | CCM_MODE_MODE_Decryption;
- NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
- NRF_CCM->SHORTS = 0;
- NRF_CCM->EVENTS_ENDCRYPT = 0;
- NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk | PPI_CHEN_CH25_Msk;
- } else {
- NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
- }
-#else
- NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
-#endif
+ /*
+ * Enable the wait for response timer. Note that cc #2 on
+ * timer 0 contains the transmit end time
+ */
+ wfr_time = NRF_TIMER0->CC[2];
+ wfr_time += cputime_usecs_to_ticks(BLE_LL_WFR_USECS);
+ ble_ll_wfr_enable(wfr_time);
+ } else {
+ /* Better not be going from rx to tx! */
+ assert(transition == BLE_PHY_TRANSITION_NONE);
+ }
- /* I want to know when 1st byte received (after address) */
- NRF_RADIO->BCC = 8; /* in bits */
- NRF_RADIO->EVENTS_ADDRESS = 0;
- NRF_RADIO->EVENTS_DEVMATCH = 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 */
- STATS_INC(ble_phy_stats, no_bufs);
- ble_phy_disable();
- }
+ /* Call transmit end callback */
+ if (g_ble_phy_data.txend_cb) {
+ g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg);
+ }
+}
- /*
- * Enable the wait for response timer. Note that cc #2 on
- * timer 0 contains the transmit end time
- */
- wfr_time = NRF_TIMER0->CC[2];
- wfr_time += cputime_usecs_to_ticks(BLE_LL_WFR_USECS);
- ble_ll_wfr_enable(wfr_time);
- } else {
- /* Better not be going from rx to tx! */
- assert(transition == BLE_PHY_TRANSITION_NONE);
- }
+static void
+ble_phy_isr(void)
+{
+ int rc;
+ uint8_t crcok;
+ uint32_t irq_en;
+ uint32_t state;
+ uint8_t *dptr;
+ struct os_mbuf *rxpdu;
+ struct ble_mbuf_hdr *ble_hdr;
- /* Call transmit end callback */
- if (g_ble_phy_data.txend_cb) {
- g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg);
- }
+ /* Read irq register to determine which interrupts are enabled */
+ irq_en = NRF_RADIO->INTENCLR;
+
+ /* Check for disabled event. This only happens for transmits now */
+ if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && NRF_RADIO->EVENTS_DISABLED) {
+ ble_phy_tx_end_isr();
}
/* We get this if we have started to receive a frame */
@@ -355,18 +384,8 @@ ble_phy_isr(void)
/* Call Link Layer receive start function */
rc = ble_ll_rx_start(g_ble_phy_data.rxpdu, g_ble_phy_data.phy_chan);
if (rc >= 0) {
+ /* Set rx started flag and enable rx end ISR */
g_ble_phy_data.phy_rx_started = 1;
- 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 */
@@ -553,6 +572,11 @@ ble_phy_init(void)
return 0;
}
+/**
+ * Puts the phy into receive mode.
+ *
+ * @return int 0: success; BLE Phy error code otherwise
+ */
int
ble_phy_rx(void)
{
@@ -569,64 +593,19 @@ ble_phy_rx(void)
return BLE_PHY_ERR_NO_BUFS;
}
- /* Set packet pointer */
-#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
- if (g_ble_phy_data.phy_encrypted) {
- NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0];
- } else {
- NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
- }
-#else
- NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
-#endif
-
/* Make sure all interrupts are disabled */
NRF_RADIO->INTENCLR = NRF_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;
- NRF_RADIO->EVENTS_DEVMATCH = 0;
-
-#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
- if (g_ble_phy_data.phy_encrypted) {
- NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
- NRF_CCM->OUTPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
- NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
- NRF_CCM->EVENTS_ERROR = 0;
- NRF_CCM->EVENTS_ENDCRYPT = 0;
- NRF_CCM->MODE = CCM_MODE_LENGTH_Msk | CCM_MODE_MODE_Decryption;
- /* XXX: can I just set this once? (i.e per connection)? In other
- words, only do this during encrypt enable? */
- NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
- NRF_CCM->SHORTS = 0;
- NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk | PPI_CHEN_CH25_Msk;
- }
-#endif
- /* XXX: could it be that I am late turning on the device? That I need
- to automatically go from rx to tx always? I dont here */
- /* 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;
-
- /* Reset the rx started flag. Used for the wait for response */
- g_ble_phy_data.phy_rx_started = 0;
+ /* Setup for rx */
+ ble_phy_rx_xcvr_setup();
/* Start the receive task in the radio */
NRF_RADIO->TASKS_RXEN = 1;
- g_ble_phy_data.phy_state = BLE_PHY_STATE_RX;
-
return 0;
}
@@ -980,4 +959,3 @@ ble_phy_rx_started(void)
{
return g_ble_phy_data.phy_rx_started;
}
-