From beb848b45c6f2c1bae30167fccafa172d8da2a97 Mon Sep 17 00:00:00 2001 From: Jeremy Gilbert Date: Sat, 15 Nov 2014 10:05:05 -0500 Subject: [PATCH 1/5] Applied fixes for various hangs now tested in production --- RFM69.cpp | 21 ++++++++++++++++++--- RFM69.h | 1 + 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/RFM69.cpp b/RFM69.cpp index 68f17d4..2b0a70c 100644 --- a/RFM69.cpp +++ b/RFM69.cpp @@ -237,7 +237,8 @@ bool RFM69::ACKRequested() { /// Should be called immediately after reception in case sender wants ACK void RFM69::sendACK(const void* buffer, byte bufferSize) { byte sender = SENDERID; - long now = millis(); + writeReg(REG_PACKETCONFIG2, (readReg(REG_PACKETCONFIG2) & 0xFB) | RF_PACKET2_RXRESTART); // avoid RX deadlocks + unsigned long now = millis(); while (!canSend() && millis()-now < RF69_CSMA_LIMIT_MS) receiveDone(); sendFrame(sender, buffer, bufferSize, false, true); } @@ -269,7 +270,9 @@ void RFM69::sendFrame(byte toAddress, const void* buffer, byte bufferSize, bool /* no need to wait for transmit mode to be ready since its handled by the radio */ setMode(RF69_MODE_TX); - while (digitalRead(_interruptPin) == 0); //wait for DIO0 to turn HIGH signalling transmission finish + unsigned long txStart = millis(); + //wait for DIO0 to turn HIGH signalling transmission finish + while (digitalRead(_interruptPin) == 0 && millis()-txStart < RF69_TX_LIMIT_GUARD_MS); //while (readReg(REG_IRQFLAGS2) & RF_IRQFLAGS2_PACKETSENT == 0x00); // Wait for ModeReady setMode(RF69_MODE_STANDBY); } @@ -288,11 +291,21 @@ void RFM69::interruptHandler() { TARGETID = SPI.transfer(0); if(!(_promiscuousMode || TARGETID==_address || TARGETID==RF69_BROADCAST_ADDR)) //match this node's address, or broadcast address or anything in promiscuous mode { + DATALEN = 0; PAYLOADLEN = 0; unselect(); //digitalWrite(4, 0); return; } + // Address situation could receive packets that are malformed and don't fit this libraries extra fields + if( PAYLOADLEN < 3 ) + { + DATALEN = 0; + PAYLOADLEN = 0; + unselect(); + return; + } + DATALEN = PAYLOADLEN - 3; SENDERID = SPI.transfer(0); byte CTLbyte = SPI.transfer(0); @@ -338,7 +351,9 @@ bool RFM69::receiveDone() { return true; } else if (_mode == RF69_MODE_RX) //already in RX no payload yet - { + { + // Trigger a packet read, just in case we missed an interrupt, avoids a potential deadlock + interruptHandler(); interrupts(); //explicitly re-enable interrupts return false; } diff --git a/RFM69.h b/RFM69.h index 4e3dff3..f4f1ca7 100644 --- a/RFM69.h +++ b/RFM69.h @@ -65,6 +65,7 @@ #define COURSE_TEMP_COEF -90 // puts the temperature reading in the ballpark, user can fine tune the returned value #define RF69_BROADCAST_ADDR 255 #define RF69_CSMA_LIMIT_MS 1000 +#define RF69_TX_LIMIT_GUARD_MS 1000 #define RF69_FSTEP 61.03515625 // == FXOSC/2^19 = 32mhz/2^19 (p13 in DS) class RFM69 { From 4f37248723f9cebdb0528a88c10b37eff84f7722 Mon Sep 17 00:00:00 2001 From: Jeremy Gilbert Date: Sat, 15 Nov 2014 10:14:59 -0500 Subject: [PATCH 2/5] Make sure all millis() are stored in unsigned longs --- RFM69.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RFM69.cpp b/RFM69.cpp index 2b0a70c..f65c040 100644 --- a/RFM69.cpp +++ b/RFM69.cpp @@ -192,7 +192,7 @@ bool RFM69::canSend() void RFM69::send(byte toAddress, const void* buffer, byte bufferSize, bool requestACK) { writeReg(REG_PACKETCONFIG2, (readReg(REG_PACKETCONFIG2) & 0xFB) | RF_PACKET2_RXRESTART); // avoid RX deadlocks - long now = millis(); + unsigned long now = millis(); while (!canSend() && millis()-now < RF69_CSMA_LIMIT_MS) receiveDone(); sendFrame(toAddress, buffer, bufferSize, requestACK, false); } @@ -204,7 +204,7 @@ void RFM69::send(byte toAddress, const void* buffer, byte bufferSize, bool reque // requires user action to read the received data and decide what to do with it // replies usually take only 5-8ms at 50kbps@915Mhz bool RFM69::sendWithRetry(byte toAddress, const void* buffer, byte bufferSize, byte retries, byte retryWaitTime) { - long sentTime; + unsigned long sentTime; for (byte i=0; i<=retries; i++) { send(toAddress, buffer, bufferSize, true); From 54b560e21f5b4bc404a2058d7361f2bdf5d13fa4 Mon Sep 17 00:00:00 2001 From: Jeremy Gilbert Date: Sat, 15 Nov 2014 21:38:11 -0500 Subject: [PATCH 3/5] Removing DATALEN = 0 - doesn't appear needed --- RFM69.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RFM69.cpp b/RFM69.cpp index f65c040..b52d3de 100644 --- a/RFM69.cpp +++ b/RFM69.cpp @@ -291,7 +291,7 @@ void RFM69::interruptHandler() { TARGETID = SPI.transfer(0); if(!(_promiscuousMode || TARGETID==_address || TARGETID==RF69_BROADCAST_ADDR)) //match this node's address, or broadcast address or anything in promiscuous mode { - DATALEN = 0; + //DATALEN = 0; PAYLOADLEN = 0; unselect(); //digitalWrite(4, 0); @@ -300,7 +300,7 @@ void RFM69::interruptHandler() { // Address situation could receive packets that are malformed and don't fit this libraries extra fields if( PAYLOADLEN < 3 ) { - DATALEN = 0; + // DATALEN = 0; PAYLOADLEN = 0; unselect(); return; From c9d08411e9a4b0a6fb1ae6e47c7135395d481479 Mon Sep 17 00:00:00 2001 From: Jeremy Gilbert Date: Thu, 4 Dec 2014 15:54:15 -0500 Subject: [PATCH 4/5] Syncing with last RFM library --- RFM69.cpp | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/RFM69.cpp b/RFM69.cpp index dbb2ed7..9b35371 100644 --- a/RFM69.cpp +++ b/RFM69.cpp @@ -238,10 +238,7 @@ bool RFM69::ACKRequested() { /// Should be called immediately after reception in case sender wants ACK void RFM69::sendACK(const void* buffer, byte bufferSize) { byte sender = SENDERID; -<<<<<<< HEAD -======= int _RSSI = RSSI; //save payload received RSSI value ->>>>>>> 0518667c1908b35933709d091dd62663ba7c3f5e writeReg(REG_PACKETCONFIG2, (readReg(REG_PACKETCONFIG2) & 0xFB) | RF_PACKET2_RXRESTART); // avoid RX deadlocks unsigned long now = millis(); while (!canSend() && millis()-now < RF69_CSMA_LIMIT_MS) receiveDone(); @@ -277,12 +274,7 @@ void RFM69::sendFrame(byte toAddress, const void* buffer, byte bufferSize, bool /* no need to wait for transmit mode to be ready since its handled by the radio */ setMode(RF69_MODE_TX); unsigned long txStart = millis(); -<<<<<<< HEAD - //wait for DIO0 to turn HIGH signalling transmission finish - while (digitalRead(_interruptPin) == 0 && millis()-txStart < RF69_TX_LIMIT_GUARD_MS); -======= while (digitalRead(_interruptPin) == 0 && millis()-txStart < RF69_TX_LIMIT_MS); //wait for DIO0 to turn HIGH signalling transmission finish ->>>>>>> 0518667c1908b35933709d091dd62663ba7c3f5e //while (readReg(REG_IRQFLAGS2) & RF_IRQFLAGS2_PACKETSENT == 0x00); // Wait for ModeReady setMode(RF69_MODE_STANDBY); } @@ -302,24 +294,12 @@ void RFM69::interruptHandler() { if(!(_promiscuousMode || TARGETID==_address || TARGETID==RF69_BROADCAST_ADDR) //match this node's address, or broadcast address or anything in promiscuous mode || PAYLOADLEN < 3) //address situation could receive packets that are malformed and don't fit this libraries extra fields { - //DATALEN = 0; PAYLOADLEN = 0; unselect(); receiveBegin(); //digitalWrite(4, 0); return; } -<<<<<<< HEAD - // Address situation could receive packets that are malformed and don't fit this libraries extra fields - if( PAYLOADLEN < 3 ) - { - // DATALEN = 0; - PAYLOADLEN = 0; - unselect(); - return; - } -======= ->>>>>>> 0518667c1908b35933709d091dd62663ba7c3f5e DATALEN = PAYLOADLEN - 3; SENDERID = SPI.transfer(0); @@ -366,9 +346,7 @@ bool RFM69::receiveDone() { return true; } else if (_mode == RF69_MODE_RX) //already in RX no payload yet - { - // Trigger a packet read, just in case we missed an interrupt, avoids a potential deadlock - interruptHandler(); + { interrupts(); //explicitly re-enable interrupts return false; } From 50e5347e7755437d84e859f97b1520294679e5f1 Mon Sep 17 00:00:00 2001 From: Jeremy Gilbert Date: Thu, 4 Dec 2014 15:56:24 -0500 Subject: [PATCH 5/5] sync to master --- RFM69.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/RFM69.h b/RFM69.h index fbd41ed..b1e5747 100644 --- a/RFM69.h +++ b/RFM69.h @@ -65,11 +65,7 @@ #define COURSE_TEMP_COEF -90 // puts the temperature reading in the ballpark, user can fine tune the returned value #define RF69_BROADCAST_ADDR 255 #define RF69_CSMA_LIMIT_MS 1000 -<<<<<<< HEAD -#define RF69_TX_LIMIT_GUARD_MS 1000 -======= #define RF69_TX_LIMIT_MS 1000 ->>>>>>> 0518667c1908b35933709d091dd62663ba7c3f5e #define RF69_FSTEP 61.03515625 // == FXOSC/2^19 = 32mhz/2^19 (p13 in DS) class RFM69 {