summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLevi Oliver <levio@google.com>2016-08-12 14:41:33 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-08-16 00:58:03 -0700
commit5a013c26ca1c3635cd06d14ae8d20f36202fb68f (patch)
tree7e9ab083069158c64bd405d61306b3d62b56a001
parente63a9403561aeaa2df8bcd0d62c6ff3820524a97 (diff)
downloadchrome-ec-5a013c26ca1c3635cd06d14ae8d20f36202fb68f.tar.gz
btle: Improved stability of ble_rx function
TEST=Used function before and after CL in a more fully implemented stack. This improved reliability and lengthened connection times. BUG=None BRANCH=None Change-Id: I60680c8855d6166e4e4a6a71639ee57464fa21ce Signed-off-by: Levi Oliver <levio@google.com> Reviewed-on: https://chromium-review.googlesource.com/370420 Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
-rw-r--r--chip/nrf51/bluetooth_le.c32
-rw-r--r--chip/nrf51/bluetooth_le.h2
2 files changed, 32 insertions, 2 deletions
diff --git a/chip/nrf51/bluetooth_le.c b/chip/nrf51/bluetooth_le.c
index 1f681a3e30..39a10d48d0 100644
--- a/chip/nrf51/bluetooth_le.c
+++ b/chip/nrf51/bluetooth_le.c
@@ -115,19 +115,38 @@ void ble_tx(struct ble_pdu *pdu)
}
static struct nrf51_ble_packet_t rx_packet;
-
int ble_rx(struct ble_pdu *pdu, int timeout, int adv)
{
uint32_t done;
uint32_t timeout_time;
+ /* Prevent illegal wait times */
+ if (timeout <= 0) {
+ NRF51_RADIO_DISABLE = 1;
+ return EC_ERROR_TIMEOUT;
+ }
+
NRF51_RADIO_PACKETPTR = (uint32_t)&rx_packet;
NRF51_RADIO_END = NRF51_RADIO_PAYLOAD = NRF51_RADIO_ADDRESS = 0;
+ /*
+ * These shortcuts cause packet transmission 150 microseconds after
+ * packet receive, as is the BTLE standard. See NRF51 manual:
+ * section 17.1.12
+ */
NRF51_RADIO_SHORTS = NRF51_RADIO_SHORTS_READY_START |
+ NRF51_RADIO_SHORTS_DISABLED_TXEN |
NRF51_RADIO_SHORTS_END_DISABLE;
NRF51_RADIO_RXEN = 1;
- timeout_time = get_time().val + timeout;
+ timeout_time = get_time().val + RADIO_SETUP_TIMEOUT;
+ while (!NRF51_RADIO_READY) {
+ if (get_time().val > timeout_time) {
+ CPRINTF("RADIO NOT SET UP IN TIME. TIMING OUT.\n");
+ return EC_ERROR_TIMEOUT;
+ }
+ }
+
+ timeout_time = get_time().val + timeout;
do {
if (get_time().val >= timeout_time) {
NRF51_RADIO_DISABLE = 1;
@@ -138,8 +157,17 @@ int ble_rx(struct ble_pdu *pdu, int timeout, int adv)
rsp_end = get_time().le.lo;
+ if (NRF51_RADIO_CRCSTATUS == 0) {
+ CPRINTF("INVALID CRC\n");
+ return EC_ERROR_CRC;
+ }
+
nrf2ble_packet(pdu, &rx_packet, adv);
+ /*
+ * Throw error if radio not yet disabled. Something has
+ * gone wrong. May be in an unexpected state.
+ */
if (NRF51_RADIO_DISABLED != 1)
return EC_ERROR_UNKNOWN;
diff --git a/chip/nrf51/bluetooth_le.h b/chip/nrf51/bluetooth_le.h
index d438259aac..a2b3807a7e 100644
--- a/chip/nrf51/bluetooth_le.h
+++ b/chip/nrf51/bluetooth_le.h
@@ -17,6 +17,8 @@
#define EXTRA_RECEIVE_BYTES 0
#define BLE_ADV_WHITEN 1
+#define RADIO_SETUP_TIMEOUT 1000
+
/* Data and Advertisements have the same PCNF values */
#define NRF51_RADIO_PCNF0_ADV_DATA \
NRF51_RADIO_PCNF0_VAL(NRF51_BLE_LENGTH_BITS, \