+TomWS1's virtualization & more; +deadlock checks
Integrate TomWS1's virtualized changes, and virtual interruptHook(). Set ACK_REQUESTED = 0 in sendACK() to avoid ACK infinite looping. Protect while(true) calls against infinite looping.
This commit is contained in:
parent
6535902a1f
commit
0c8fbacc5c
24
RFM69.cpp
24
RFM69.cpp
|
|
@ -90,9 +90,11 @@ bool RFM69::initialize(uint8_t freqBand, uint8_t nodeID, uint8_t networkID)
|
||||||
digitalWrite(_slaveSelectPin, HIGH);
|
digitalWrite(_slaveSelectPin, HIGH);
|
||||||
pinMode(_slaveSelectPin, OUTPUT);
|
pinMode(_slaveSelectPin, OUTPUT);
|
||||||
SPI.begin();
|
SPI.begin();
|
||||||
|
unsigned long start = millis();
|
||||||
do writeReg(REG_SYNCVALUE1, 0xAA); while (readReg(REG_SYNCVALUE1) != 0xAA);
|
uint8_t timeout = 50;
|
||||||
do writeReg(REG_SYNCVALUE1, 0x55); while (readReg(REG_SYNCVALUE1) != 0x55);
|
do writeReg(REG_SYNCVALUE1, 0xAA); while (readReg(REG_SYNCVALUE1) != 0xaa && millis()-start < timeout);
|
||||||
|
start = millis();
|
||||||
|
do writeReg(REG_SYNCVALUE1, 0x55); while (readReg(REG_SYNCVALUE1) != 0x55 && millis()-start < timeout);
|
||||||
|
|
||||||
for (uint8_t i = 0; CONFIG[i][0] != 255; i++)
|
for (uint8_t i = 0; CONFIG[i][0] != 255; i++)
|
||||||
writeReg(CONFIG[i][0], CONFIG[i][1]);
|
writeReg(CONFIG[i][0], CONFIG[i][1]);
|
||||||
|
|
@ -103,7 +105,10 @@ bool RFM69::initialize(uint8_t freqBand, uint8_t nodeID, uint8_t networkID)
|
||||||
|
|
||||||
setHighPower(_isRFM69HW); // called regardless if it's a RFM69W or RFM69HW
|
setHighPower(_isRFM69HW); // called regardless if it's a RFM69W or RFM69HW
|
||||||
setMode(RF69_MODE_STANDBY);
|
setMode(RF69_MODE_STANDBY);
|
||||||
while ((readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00); // wait for ModeReady
|
start = millis();
|
||||||
|
while (((readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00) && millis()-start < timeout); // wait for ModeReady
|
||||||
|
if (millis()-start >= timeout)
|
||||||
|
return false;
|
||||||
attachInterrupt(_interruptNum, RFM69::isr0, RISING);
|
attachInterrupt(_interruptNum, RFM69::isr0, RISING);
|
||||||
|
|
||||||
selfPointer = this;
|
selfPointer = this;
|
||||||
|
|
@ -257,6 +262,7 @@ bool RFM69::ACKRequested() {
|
||||||
|
|
||||||
// should be called immediately after reception in case sender wants ACK
|
// should be called immediately after reception in case sender wants ACK
|
||||||
void RFM69::sendACK(const void* buffer, uint8_t bufferSize) {
|
void RFM69::sendACK(const void* buffer, uint8_t bufferSize) {
|
||||||
|
ACK_REQUESTED = 0; // TWS added to make sure we don't end up in a timing race and infinite loop sending Acks
|
||||||
uint8_t sender = SENDERID;
|
uint8_t sender = SENDERID;
|
||||||
int16_t _RSSI = RSSI; // save payload received RSSI value
|
int16_t _RSSI = RSSI; // save payload received RSSI value
|
||||||
writeReg(REG_PACKETCONFIG2, (readReg(REG_PACKETCONFIG2) & 0xFB) | RF_PACKET2_RXRESTART); // avoid RX deadlocks
|
writeReg(REG_PACKETCONFIG2, (readReg(REG_PACKETCONFIG2) & 0xFB) | RF_PACKET2_RXRESTART); // avoid RX deadlocks
|
||||||
|
|
@ -277,9 +283,9 @@ void RFM69::sendFrame(uint8_t toAddress, const void* buffer, uint8_t bufferSize,
|
||||||
// control byte
|
// control byte
|
||||||
uint8_t CTLbyte = 0x00;
|
uint8_t CTLbyte = 0x00;
|
||||||
if (sendACK)
|
if (sendACK)
|
||||||
CTLbyte = 0x80;
|
CTLbyte = RFM69_CTL_SENDACK;
|
||||||
else if (requestACK)
|
else if (requestACK)
|
||||||
CTLbyte = 0x40;
|
CTLbyte = RFM69_CTL_REQACK;
|
||||||
|
|
||||||
// write to FIFO
|
// write to FIFO
|
||||||
select();
|
select();
|
||||||
|
|
@ -328,8 +334,10 @@ void RFM69::interruptHandler() {
|
||||||
SENDERID = SPI.transfer(0);
|
SENDERID = SPI.transfer(0);
|
||||||
uint8_t CTLbyte = SPI.transfer(0);
|
uint8_t CTLbyte = SPI.transfer(0);
|
||||||
|
|
||||||
ACK_RECEIVED = CTLbyte & 0x80; // extract ACK-received flag
|
ACK_RECEIVED = CTLbyte & RFM69_CTL_SENDACK; // extract ACK-received flag
|
||||||
ACK_REQUESTED = CTLbyte & 0x40; // extract ACK-requested flag
|
ACK_REQUESTED = CTLbyte & RFM69_CTL_REQACK; // extract ACK-requested flag
|
||||||
|
|
||||||
|
interruptHook(CTLbyte); // TWS: hook to derived class interrupt function
|
||||||
|
|
||||||
for (uint8_t i = 0; i < DATALEN; i++)
|
for (uint8_t i = 0; i < DATALEN; i++)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
29
RFM69.h
29
RFM69.h
|
|
@ -71,6 +71,10 @@
|
||||||
#define RF69_TX_LIMIT_MS 1000
|
#define RF69_TX_LIMIT_MS 1000
|
||||||
#define RF69_FSTEP 61.03515625 // == FXOSC / 2^19 = 32MHz / 2^19 (p13 in datasheet)
|
#define RF69_FSTEP 61.03515625 // == FXOSC / 2^19 = 32MHz / 2^19 (p13 in datasheet)
|
||||||
|
|
||||||
|
// TWS: define CTLbyte bits
|
||||||
|
#define RFM69_CTL_SENDACK 0x80
|
||||||
|
#define RFM69_CTL_REQACK 0x40
|
||||||
|
|
||||||
class RFM69 {
|
class RFM69 {
|
||||||
public:
|
public:
|
||||||
static volatile uint8_t DATA[RF69_MAX_DATA_LEN]; // recv/xmit buf, including header & crc bytes
|
static volatile uint8_t DATA[RF69_MAX_DATA_LEN]; // recv/xmit buf, including header & crc bytes
|
||||||
|
|
@ -97,20 +101,20 @@ class RFM69 {
|
||||||
void setAddress(uint8_t addr);
|
void setAddress(uint8_t addr);
|
||||||
void setNetwork(uint8_t networkID);
|
void setNetwork(uint8_t networkID);
|
||||||
bool canSend();
|
bool canSend();
|
||||||
void send(uint8_t toAddress, const void* buffer, uint8_t bufferSize, bool requestACK=false);
|
virtual void send(uint8_t toAddress, const void* buffer, uint8_t bufferSize, bool requestACK=false);
|
||||||
bool sendWithRetry(uint8_t toAddress, const void* buffer, uint8_t bufferSize, uint8_t retries=2, uint8_t retryWaitTime=40); // 40ms roundtrip req for 61byte packets
|
virtual bool sendWithRetry(uint8_t toAddress, const void* buffer, uint8_t bufferSize, uint8_t retries=2, uint8_t retryWaitTime=40); // 40ms roundtrip req for 61byte packets
|
||||||
bool receiveDone();
|
virtual bool receiveDone();
|
||||||
bool ACKReceived(uint8_t fromNodeID);
|
bool ACKReceived(uint8_t fromNodeID);
|
||||||
bool ACKRequested();
|
bool ACKRequested();
|
||||||
void sendACK(const void* buffer = "", uint8_t bufferSize=0);
|
virtual void sendACK(const void* buffer = "", uint8_t bufferSize=0);
|
||||||
uint32_t getFrequency();
|
uint32_t getFrequency();
|
||||||
void setFrequency(uint32_t freqHz);
|
void setFrequency(uint32_t freqHz);
|
||||||
void encrypt(const char* key);
|
void encrypt(const char* key);
|
||||||
void setCS(uint8_t newSPISlaveSelect);
|
void setCS(uint8_t newSPISlaveSelect);
|
||||||
int16_t readRSSI(bool forceTrigger=false);
|
int16_t readRSSI(bool forceTrigger=false);
|
||||||
void promiscuous(bool onOff=true);
|
void promiscuous(bool onOff=true);
|
||||||
void setHighPower(bool onOFF=true); // has to be called after initialize() for RFM69HW
|
virtual void setHighPower(bool onOFF=true); // has to be called after initialize() for RFM69HW
|
||||||
void setPowerLevel(uint8_t level); // reduce/increase transmit power level
|
virtual void setPowerLevel(uint8_t level); // reduce/increase transmit power level
|
||||||
void sleep();
|
void sleep();
|
||||||
uint8_t readTemperature(uint8_t calFactor=0); // get CMOS temperature (8bit)
|
uint8_t readTemperature(uint8_t calFactor=0); // get CMOS temperature (8bit)
|
||||||
void rcCalibration(); // calibrate the internal RC oscillator for use in wide temperature variations - see datasheet section [4.3.5. RC Timer Accuracy]
|
void rcCalibration(); // calibrate the internal RC oscillator for use in wide temperature variations - see datasheet section [4.3.5. RC Timer Accuracy]
|
||||||
|
|
@ -123,7 +127,8 @@ class RFM69 {
|
||||||
protected:
|
protected:
|
||||||
static void isr0();
|
static void isr0();
|
||||||
void virtual interruptHandler();
|
void virtual interruptHandler();
|
||||||
void sendFrame(uint8_t toAddress, const void* buffer, uint8_t size, bool requestACK=false, bool sendACK=false);
|
virtual void interruptHook(uint8_t CTLbyte) {};
|
||||||
|
virtual void sendFrame(uint8_t toAddress, const void* buffer, uint8_t size, bool requestACK=false, bool sendACK=false);
|
||||||
|
|
||||||
static RFM69* selfPointer;
|
static RFM69* selfPointer;
|
||||||
uint8_t _slaveSelectPin;
|
uint8_t _slaveSelectPin;
|
||||||
|
|
@ -136,11 +141,11 @@ class RFM69 {
|
||||||
uint8_t _SPCR;
|
uint8_t _SPCR;
|
||||||
uint8_t _SPSR;
|
uint8_t _SPSR;
|
||||||
|
|
||||||
void receiveBegin();
|
virtual void receiveBegin();
|
||||||
void setMode(uint8_t mode);
|
virtual void setMode(uint8_t mode);
|
||||||
void setHighPowerRegs(bool onOff);
|
virtual void setHighPowerRegs(bool onOff);
|
||||||
void select();
|
virtual void select();
|
||||||
void unselect();
|
virtual void unselect();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Loading…
Reference in New Issue