You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2016/04/28 02:14:48 UTC
[49/50] [abbrv] incubator-mynewt-core git commit: MYNEWT-85: Fix BLE
timing for start of connection events. MYNEWT-283: Slave anchor point now set
correctly on CRC error.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8ddc20ee/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 cecbe60..609242c 100644
--- a/net/nimble/drivers/nrf52/src/ble_phy.c
+++ b/net/nimble/drivers/nrf52/src/ble_phy.c
@@ -21,6 +21,7 @@
#include <string.h>
#include <assert.h>
#include "os/os.h"
+#include "ble/xcvr.h"
#include "bsp/cmsis_nvic.h"
#include "nimble/ble.h"
#include "nimble/nimble_opt.h"
@@ -48,6 +49,7 @@
/* Maximum length of frames */
#define NRF_MAXLEN (255)
#define NRF_BALEN (3) /* For base address of 3 bytes */
+#define NRF_RX_START_OFFSET (5)
/* Maximum tx power */
#define NRF_TX_PWR_MAX_DBM (4)
@@ -63,6 +65,7 @@ struct ble_phy_obj
uint8_t phy_transition;
uint8_t phy_rx_started;
uint8_t phy_encrypted;
+ uint8_t phy_tx_pyld_len;
uint32_t phy_access_address;
struct os_mbuf *rxpdu;
void *txend_arg;
@@ -89,6 +92,7 @@ STATS_SECT_START(ble_phy_stats)
STATS_SECT_ENTRY(rx_aborts)
STATS_SECT_ENTRY(rx_valid)
STATS_SECT_ENTRY(rx_crc_err)
+ STATS_SECT_ENTRY(rx_late)
STATS_SECT_ENTRY(no_bufs)
STATS_SECT_ENTRY(radio_state_errs)
STATS_SECT_ENTRY(rx_hw_err)
@@ -106,6 +110,7 @@ STATS_NAME_START(ble_phy_stats)
STATS_NAME(ble_phy_stats, rx_aborts)
STATS_NAME(ble_phy_stats, rx_valid)
STATS_NAME(ble_phy_stats, rx_crc_err)
+ STATS_NAME(ble_phy_stats, rx_late)
STATS_NAME(ble_phy_stats, no_bufs)
STATS_NAME(ble_phy_stats, radio_state_errs)
STATS_NAME(ble_phy_stats, rx_hw_err)
@@ -220,8 +225,7 @@ nrf_wait_disabled(void)
}
/**
- * Setup transceiver for receive
- *
+ * Setup transceiver for receive.
*/
static void
ble_phy_rx_xcvr_setup(void)
@@ -245,6 +249,9 @@ ble_phy_rx_xcvr_setup(void)
NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
#endif
+ /* We dont want to trigger TXEN on output compare match */
+ NRF_PPI->CHENCLR = PPI_CHEN_CH20_Msk;
+
/* 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;
@@ -280,7 +287,7 @@ ble_phy_tx_end_isr(void)
/* 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]);
+ g_ble_phy_data.phy_encrypted, NRF_TIMER0->CC[1]);
/* Clear events and clear interrupt on disabled event */
NRF_RADIO->EVENTS_DISABLED = 0;
@@ -313,14 +320,16 @@ ble_phy_tx_end_isr(void)
}
/*
- * Enable the wait for response timer. Note that cc #2 on
- * timer 0 contains the transmit end time
+ * Enable the wait for response timer. Note that cc #1 on
+ * timer 0 contains the transmit start time
*/
- wfr_time = NRF_TIMER0->CC[2];
+ wfr_time = NRF_TIMER0->CC[1] - BLE_TX_LEN_USECS_M(NRF_RX_START_OFFSET);
+ wfr_time += BLE_TX_DUR_USECS_M(g_ble_phy_data.phy_tx_pyld_len);
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! */
+ /* Disable automatic TXEN */
+ NRF_PPI->CHENCLR = PPI_CHEN_CH20_Msk;
assert(transition == BLE_PHY_TRANSITION_NONE);
}
@@ -331,147 +340,165 @@ ble_phy_tx_end_isr(void)
}
static void
-ble_phy_isr(void)
+ble_phy_rx_end_isr(void)
{
int rc;
- uint8_t crcok;
- uint32_t irq_en;
- uint32_t state;
uint8_t *dptr;
+ uint8_t crcok;
struct os_mbuf *rxpdu;
struct ble_mbuf_hdr *ble_hdr;
- /* Read irq register to determine which interrupts are enabled */
- irq_en = NRF_RADIO->INTENCLR;
+ /* Clear events and clear interrupt */
+ NRF_RADIO->EVENTS_END = 0;
+ NRF_RADIO->INTENCLR = RADIO_INTENCLR_END_Msk;
- /* 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();
- }
+ /* Disable automatic RXEN */
+ NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk;
- /* 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;
+ /* Set RSSI and CRC status flag in header */
+ ble_hdr = BLE_MBUF_HDR_PTR(g_ble_phy_data.rxpdu);
+ assert(NRF_RADIO->EVENTS_RSSIEND != 0);
+ ble_hdr->rxinfo.rssi = -1 * NRF_RADIO->RSSISAMPLE;
- assert(g_ble_phy_data.rxpdu != NULL);
+ dptr = g_ble_phy_data.rxpdu->om_data;
+
+ /* Count PHY crc errors and valid packets */
+ crcok = (uint8_t)NRF_RADIO->CRCSTATUS;
+ if (!crcok) {
+ STATS_INC(ble_phy_stats, rx_crc_err);
+ } else {
+ STATS_INC(ble_phy_stats, rx_valid);
+ ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_CRC_OK;
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+ if (g_ble_phy_data.phy_encrypted) {
+ /* Only set MIC failure flag if frame is not zero length */
+ if ((dptr[1] != 0) && (NRF_CCM->MICSTATUS == 0)) {
+ ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_MIC_FAILURE;
+ }
- /* Wait to get 1st byte of frame */
- while (1) {
- state = NRF_RADIO->STATE;
- if (NRF_RADIO->EVENTS_BCMATCH != 0) {
- break;
+ /*
+ * XXX: not sure how to deal with this. This should not
+ * be a MIC failure but we should not hand it up. I guess
+ * this is just some form of rx error and that is how we
+ * handle it? For now, just set CRC error flags
+ */
+ if (NRF_CCM->EVENTS_ERROR) {
+ STATS_INC(ble_phy_stats, rx_hw_err);
+ ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK;
}
/*
- * If state is disabled, we should have the BCMATCH. If not,
- * something is wrong!
+ * XXX: This is a total hack work-around for now but I dont
+ * know what else to do. If ENDCRYPT is not set and we are
+ * encrypted we need to not trust this frame and drop it.
*/
- if (state == RADIO_STATE_STATE_Disabled) {
- NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
- NRF_RADIO->SHORTS = 0;
- goto phy_isr_exit;
+ if (NRF_CCM->EVENTS_ENDCRYPT == 0) {
+ STATS_INC(ble_phy_stats, rx_hw_err);
+ ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK;
}
}
+#endif
+ }
- /* Initialize flags, channel and state in ble header at rx start */
- ble_hdr = BLE_MBUF_HDR_PTR(g_ble_phy_data.rxpdu);
- ble_hdr->rxinfo.flags = ble_ll_state_get();
- ble_hdr->rxinfo.channel = g_ble_phy_data.phy_chan;
- ble_hdr->rxinfo.handle = 0;
-
- /* 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;
- NRF_RADIO->INTENSET = RADIO_INTENSET_END_Msk;
- } else {
- /* Disable PHY */
- ble_phy_disable();
- irq_en = 0;
- STATS_INC(ble_phy_stats, rx_aborts);
- }
+ /* Call Link Layer receive payload function */
+ rxpdu = g_ble_phy_data.rxpdu;
+ g_ble_phy_data.rxpdu = NULL;
- /* Count rx starts */
- STATS_INC(ble_phy_stats, rx_starts);
+ /*
+ * XXX: This is a horrible ugly hack to deal with the RAM S1 byte
+ * that is not sent over the air but is present here. Simply move the
+ * data pointer to deal with it. Fix this later. Do this in the nrf52
+ */
+ dptr[2] = dptr[1];
+ dptr[1] = dptr[0];
+ rxpdu->om_data += 1;
+
+ rc = ble_ll_rx_end(rxpdu, ble_hdr);
+ if (rc < 0) {
+ ble_phy_disable();
}
+}
- /* 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;
-
- /* Set RSSI and CRC status flag in header */
- ble_hdr = BLE_MBUF_HDR_PTR(g_ble_phy_data.rxpdu);
- assert(NRF_RADIO->EVENTS_RSSIEND != 0);
- ble_hdr->rxinfo.rssi = -1 * NRF_RADIO->RSSISAMPLE;
- ble_hdr->end_cputime = NRF_TIMER0->CC[2];
- dptr = g_ble_phy_data.rxpdu->om_data;
-
- /* Count PHY crc errors and valid packets */
- crcok = (uint8_t)NRF_RADIO->CRCSTATUS;
- if (!crcok) {
- STATS_INC(ble_phy_stats, rx_crc_err);
- } else {
- STATS_INC(ble_phy_stats, rx_valid);
- ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_CRC_OK;
-#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
- if (g_ble_phy_data.phy_encrypted) {
- /* Only set MIC failure flag if frame is not zero length */
- if ((dptr[1] != 0) && (NRF_CCM->MICSTATUS == 0)) {
- ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_MIC_FAILURE;
- }
-
- /*
- * XXX: not sure how to deal with this. This should not
- * be a MIC failure but we should not hand it up. I guess
- * this is just some form of rx error and that is how we
- * handle it? For now, just set CRC error flags
- */
- if (NRF_CCM->EVENTS_ERROR) {
- STATS_INC(ble_phy_stats, rx_hw_err);
- ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK;
- }
-
- /*
- * XXX: This is a total hack work-around for now but I dont
- * know what else to do. If ENDCRYPT is not set and we are
- * encrypted we need to not trust this frame and drop it.
- */
- if (NRF_CCM->EVENTS_ENDCRYPT == 0) {
- STATS_INC(ble_phy_stats, rx_hw_err);
- ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK;
- }
- }
-#endif
- }
+static void
+ble_phy_rx_start_isr(void)
+{
+ int rc;
+ uint32_t state;
+ struct ble_mbuf_hdr *ble_hdr;
+
+ /* Clear events and clear interrupt */
+ NRF_RADIO->EVENTS_ADDRESS = 0;
+ NRF_RADIO->INTENCLR = RADIO_INTENCLR_ADDRESS_Msk;
+
+ assert(g_ble_phy_data.rxpdu != NULL);
- /* Call Link Layer receive payload function */
- rxpdu = g_ble_phy_data.rxpdu;
- 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;
+ }
/*
- * XXX: This is a horrible ugly hack to deal with the RAM S1 byte
- * that is not sent over the air but is present here. Simply move the
- * data pointer to deal with it. Fix this later. Do this in the nrf52
+ * If state is disabled, we should have the BCMATCH. If not,
+ * something is wrong!
*/
- dptr[2] = dptr[1];
- dptr[1] = dptr[0];
- rxpdu->om_data += 1;
-
- rc = ble_ll_rx_end(rxpdu, ble_hdr);
- if (rc < 0) {
- /* Disable the PHY. */
- ble_phy_disable();
+ if (state == RADIO_STATE_STATE_Disabled) {
+ NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
+ NRF_RADIO->SHORTS = 0;
+ return;
}
}
-phy_isr_exit:
+ /* Initialize flags, channel and state in ble header at rx start */
+ ble_hdr = BLE_MBUF_HDR_PTR(g_ble_phy_data.rxpdu);
+ ble_hdr->rxinfo.flags = ble_ll_state_get();
+ ble_hdr->rxinfo.channel = g_ble_phy_data.phy_chan;
+ ble_hdr->rxinfo.handle = 0;
+ ble_hdr->beg_cputime = NRF_TIMER0->CC[1] -
+ BLE_TX_LEN_USECS_M(NRF_RX_START_OFFSET);
+
+ /* 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;
+ NRF_RADIO->INTENSET = RADIO_INTENSET_END_Msk;
+ } else {
+ /* Disable PHY */
+ ble_phy_disable();
+ STATS_INC(ble_phy_stats, rx_aborts);
+ }
+
+ /* Count rx starts */
+ STATS_INC(ble_phy_stats, rx_starts);
+}
+
+static void
+ble_phy_isr(void)
+{
+ uint32_t irq_en;
+
+ /* 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 */
+ if ((irq_en & RADIO_INTENCLR_ADDRESS_Msk) && NRF_RADIO->EVENTS_ADDRESS) {
+ ble_phy_rx_start_isr();
+ }
+
+ /* Receive packet end (we dont enable this for transmit) */
+ if ((irq_en & RADIO_INTENCLR_END_Msk) && NRF_RADIO->EVENTS_END) {
+ ble_phy_rx_end_isr();
+ }
+
/* Ensures IRQ is cleared */
- state = NRF_RADIO->SHORTS;
+ irq_en = NRF_RADIO->SHORTS;
/* Count # of interrupts */
STATS_INC(ble_phy_stats, phy_isrs);
@@ -538,11 +565,8 @@ ble_phy_init(void)
/* Configure IFS */
NRF_RADIO->TIFS = BLE_LL_IFS;
- /*
- * Enable the pre-programmed PPI to capture the time when a receive
- * or transmit ends
- */
- NRF_PPI->CHENSET = PPI_CHEN_CH27_Msk;
+ /* Captures tx/rx start in timer0 capture 1 */
+ NRF_PPI->CHENSET = PPI_CHEN_CH26_Msk;
#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
NRF_CCM->INTENCLR = 0xffffffff;
@@ -603,8 +627,12 @@ ble_phy_rx(void)
/* Setup for rx */
ble_phy_rx_xcvr_setup();
- /* Start the receive task in the radio */
- NRF_RADIO->TASKS_RXEN = 1;
+ /* Start the receive task in the radio if not automatically going to rx */
+ if ((NRF_PPI->CHEN & PPI_CHEN_CH21_Msk) == 0) {
+ NRF_RADIO->TASKS_RXEN = 1;
+ }
+
+ ble_ll_log(BLE_LL_LOG_ID_PHY_RX, g_ble_phy_data.phy_encrypted, 0, 0);
return 0;
}
@@ -656,11 +684,76 @@ ble_phy_set_txend_cb(ble_phy_tx_end_func txend_cb, void *arg)
g_ble_phy_data.txend_arg = arg;
}
+/**
+ * Called to set the start time of a transmission.
+ *
+ * This function is called to set the start time when we are not going from
+ * rx to tx automatically.
+ *
+ * NOTE: care must be taken when calling this function. The channel should
+ * already be set.
+ *
+ * @param cputime
+ *
+ * @return int
+ */
+int
+ble_phy_tx_set_start_time(uint32_t cputime)
+{
+ int rc;
+
+ NRF_TIMER0->CC[0] = cputime;
+ NRF_PPI->CHENSET = PPI_CHEN_CH20_Msk;
+ NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk;
+ if ((int32_t)(cputime_get32() - cputime) >= 0) {
+ STATS_INC(ble_phy_stats, tx_late);
+ ble_phy_disable();
+ rc = BLE_PHY_ERR_TX_LATE;
+ } else {
+ rc = 0;
+ }
+ return rc;
+}
+
+/**
+ * Called to set the start time of a reception
+ *
+ * This function acts a bit differently than transmit. If we are late getting
+ * here we will still attempt to receive.
+ *
+ * NOTE: care must be taken when calling this function. The channel should
+ * already be set.
+ *
+ * @param cputime
+ *
+ * @return int
+ */
+int
+ble_phy_rx_set_start_time(uint32_t cputime)
+{
+ int rc;
+
+ NRF_TIMER0->CC[0] = cputime;
+ NRF_PPI->CHENCLR = PPI_CHEN_CH20_Msk;
+ NRF_PPI->CHENSET = PPI_CHEN_CH21_Msk;
+ if ((int32_t)(cputime_get32() - cputime) >= 0) {
+ STATS_INC(ble_phy_stats, rx_late);
+ NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk;
+ NRF_RADIO->TASKS_RXEN = 1;
+ rc = BLE_PHY_ERR_TX_LATE;
+ } else {
+ rc = 0;
+ }
+ return rc;
+}
+
+
int
-ble_phy_tx(struct os_mbuf *txpdu, uint8_t beg_trans, uint8_t end_trans)
+ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
{
int rc;
uint8_t *dptr;
+ uint8_t payload_len;
uint32_t state;
uint32_t shortcuts;
struct ble_mbuf_hdr *ble_hdr;
@@ -668,37 +761,18 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t beg_trans, uint8_t end_trans)
/* Better have a pdu! */
assert(txpdu != NULL);
- /* If radio is not disabled, */
+ /*
+ * This check is to make sure that the radio is not in a state where
+ * it is moving to disabled state. If so, let it get there.
+ */
nrf_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();
- STATS_INC(ble_phy_stats, radio_state_errs);
- return BLE_PHY_ERR_RADIO_STATE;
- }
+ ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
+ payload_len = ble_hdr->txinfo.pyld_len;
#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
if (g_ble_phy_data.phy_encrypted) {
- /* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */
- ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
dptr = (uint8_t *)&g_ble_phy_enc_buf[0];
- dptr[0] = ble_hdr->txinfo.hdr_byte;
- dptr[1] = ble_hdr->txinfo.pyld_len;
- dptr[2] = 0;
- dptr += 3;
-
- NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
NRF_CCM->SHORTS = 1;
NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
NRF_CCM->OUTPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
@@ -709,27 +783,18 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t beg_trans, uint8_t end_trans)
NRF_PPI->CHENCLR = PPI_CHEN_CH25_Msk;
NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk;
} else {
- /* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */
- ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
dptr = (uint8_t *)&g_ble_phy_txrx_buf[0];
- dptr[0] = ble_hdr->txinfo.hdr_byte;
- dptr[1] = ble_hdr->txinfo.pyld_len;
- dptr[2] = 0;
- dptr += 3;
-
- NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
}
#else
- /* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */
- ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
dptr = (uint8_t *)&g_ble_phy_txrx_buf[0];
+#endif
+
+ /* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */
dptr[0] = ble_hdr->txinfo.hdr_byte;
- dptr[1] = ble_hdr->txinfo.pyld_len;
+ dptr[1] = payload_len;
dptr[2] = 0;
dptr += 3;
-
NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
-#endif
/* Clear the ready, end and disabled events */
NRF_RADIO->EVENTS_READY = 0;
@@ -747,36 +812,26 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t beg_trans, uint8_t end_trans)
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 transmitted payload length */
+ g_ble_phy_data.phy_tx_pyld_len = payload_len;
/* Set the PHY transition */
g_ble_phy_data.phy_transition = end_trans;
- /* Read back radio state. If in TXRU, we are fine */
+ /* If we already started transmitting, abort it! */
state = NRF_RADIO->STATE;
- if (state == RADIO_STATE_STATE_TxRu) {
+ if (state != RADIO_STATE_STATE_Tx) {
/* Copy data from mbuf into transmit buffer */
- os_mbuf_copydata(txpdu, ble_hdr->txinfo.offset,
- ble_hdr->txinfo.pyld_len, dptr);
+ os_mbuf_copydata(txpdu, ble_hdr->txinfo.offset, payload_len, dptr);
/* Set phy state to transmitting and count packet statistics */
g_ble_phy_data.phy_state = BLE_PHY_STATE_TX;
STATS_INC(ble_phy_stats, tx_good);
- STATS_INCN(ble_phy_stats, tx_bytes,
- ble_hdr->txinfo.pyld_len + BLE_LL_PDU_HDR_LEN);
+ STATS_INCN(ble_phy_stats, tx_bytes, payload_len + BLE_LL_PDU_HDR_LEN);
rc = BLE_ERR_SUCCESS;
} else {
- if (state == RADIO_STATE_STATE_Tx) {
- STATS_INC(ble_phy_stats, tx_late);
- } else {
- STATS_INC(ble_phy_stats, tx_fail);
- }
-
- /* Frame failed to transmit */
ble_phy_disable();
+ STATS_INC(ble_phy_stats, tx_late);
rc = BLE_PHY_ERR_RADIO_STATE;
}
@@ -916,6 +971,7 @@ ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit)
* -> Turn off all phy interrupts.
* -> Disable internal shortcuts.
* -> Disable the radio.
+ * -> Make sure we wont automatically go to rx/tx on output compare
* -> Sets phy state to idle.
* -> Clears any pending irqs in the NVIC. Might not be necessary but we do
* it as a precaution.
@@ -928,6 +984,7 @@ ble_phy_disable(void)
NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
NRF_RADIO->SHORTS = 0;
NRF_RADIO->TASKS_DISABLE = 1;
+ NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk | PPI_CHEN_CH20_Msk;
NVIC_ClearPendingIRQ(RADIO_IRQn);
g_ble_phy_data.phy_state = BLE_PHY_STATE_IDLE;
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8ddc20ee/net/nimble/include/nimble/ble.h
----------------------------------------------------------------------
diff --git a/net/nimble/include/nimble/ble.h b/net/nimble/include/nimble/ble.h
index 894dff4..c0b5b74 100644
--- a/net/nimble/include/nimble/ble.h
+++ b/net/nimble/include/nimble/ble.h
@@ -88,7 +88,7 @@ struct ble_mbuf_hdr
struct ble_mbuf_hdr_rxinfo rxinfo;
struct ble_mbuf_hdr_txinfo txinfo;
};
- uint32_t end_cputime;
+ uint32_t beg_cputime;
};
/*