Skip to content

Commit

Permalink
Rebase to up to date RFM69 version
Browse files Browse the repository at this point in the history
Add timeout handling for startup, hook for  rfm69 derivated clase - to
support ATC. Change short pauses to delayMicroseconds from wiringPi
library for beter accuracy
  • Loading branch information
abouillot committed Dec 12, 2015
1 parent be14c83 commit 51cbb29
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 27 deletions.
35 changes: 21 additions & 14 deletions piGateway/rfm69.cpp
Expand Up @@ -113,9 +113,11 @@ bool RFM69::initialize(uint8_t freqBand, uint8_t nodeID, uint8_t networkID)
pinMode(_slaveSelectPin, OUTPUT);
SPI.begin();
#endif

do writeReg(REG_SYNCVALUE1, 0xAA); while (readReg(REG_SYNCVALUE1) != 0xAA);
do writeReg(REG_SYNCVALUE1, 0x55); while (readReg(REG_SYNCVALUE1) != 0x55);
unsigned long start = millis();
uint8_t timeout = 50;
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++)
writeReg(CONFIG[i][0], CONFIG[i][1]);
Expand All @@ -126,7 +128,10 @@ bool RFM69::initialize(uint8_t freqBand, uint8_t nodeID, uint8_t networkID)

setHighPower(_isRFM69HW); // called regardless if it's a RFM69W or RFM69HW
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;
#ifdef RASPBERRY
// Attach the Interupt
wiringPiSetup();
Expand Down Expand Up @@ -348,11 +353,12 @@ bool RFM69::ACKRequested() {

// should be called immediately after reception in case sender wants ACK
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;
int16_t _RSSI = RSSI; // save payload received RSSI value
writeReg(REG_PACKETCONFIG2, (readReg(REG_PACKETCONFIG2) & 0xFB) | RF_PACKET2_RXRESTART); // avoid RX deadlocks
uint32_t now = millis();
while (!canSend() && millis() - now < RF69_CSMA_LIMIT_MS) { usleep(MICROSLEEP_LENGTH); /* printf(".");*/ receiveDone();}
while (!canSend() && millis() - now < RF69_CSMA_LIMIT_MS) { delayMicroseconds(MICROSLEEP_LENGTH); /* printf(".");*/ receiveDone();}
sendFrame(sender, buffer, bufferSize, false, true);
RSSI = _RSSI; // restore payload RSSI
}
Expand All @@ -368,9 +374,9 @@ void RFM69::sendFrame(uint8_t toAddress, const void* buffer, uint8_t bufferSize,
// control byte
uint8_t CTLbyte = 0x00;
if (sendACK)
CTLbyte = 0x80;
CTLbyte = RFM69_CTL_SENDACK;
else if (requestACK)
CTLbyte = 0x40;
CTLbyte = RFM69_CTL_REQACK;

#ifdef RASPBERRY
unsigned char thedata[63];
Expand Down Expand Up @@ -430,7 +436,7 @@ void RFM69::interruptHandler() {
thedata[1] = 0; // PAYLOADLEN
thedata[2] = 0; // TargetID
wiringPiSPIDataRW(SPI_DEVICE, thedata, 3);
usleep(MICROSLEEP_LENGTH);
delayMicroseconds(MICROSLEEP_LENGTH);

PAYLOADLEN = thedata[1];
PAYLOADLEN = PAYLOADLEN > 66 ? 66 : PAYLOADLEN; // precaution
Expand Down Expand Up @@ -476,9 +482,10 @@ void RFM69::interruptHandler() {
SENDERID = SPI.transfer(0);
uint8_t CTLbyte = SPI.transfer(0);

ACK_RECEIVED = CTLbyte & 0x80; // extract ACK-received flag
ACK_REQUESTED = CTLbyte & 0x40; // extract ACK-requested flag

ACK_RECEIVED = CTLbyte & RFM69_CTL_SENDACK; // extract ACK-received 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++)
{
DATA[i] = SPI.transfer(0);
Expand Down Expand Up @@ -560,7 +567,7 @@ void RFM69::encrypt(const char* key) {
}

wiringPiSPIDataRW(SPI_DEVICE, thedata, 17);
usleep(MICROSLEEP_LENGTH);
delayMicroseconds(MICROSLEEP_LENGTH);
}

writeReg(REG_PACKETCONFIG2, (readReg(REG_PACKETCONFIG2) & 0xFE) | (key ? 1 : 0));
Expand Down Expand Up @@ -600,7 +607,7 @@ uint8_t RFM69::readReg(uint8_t addr)
thedata[1] = 0;

wiringPiSPIDataRW(SPI_DEVICE, thedata, 2);
usleep(MICROSLEEP_LENGTH);
delayMicroseconds(MICROSLEEP_LENGTH);

//printf("%x %x\n", addr, thedata[1]);
return thedata[1];
Expand All @@ -622,7 +629,7 @@ void RFM69::writeReg(uint8_t addr, uint8_t value)
thedata[1] = value;

wiringPiSPIDataRW(SPI_DEVICE, thedata, 2);
usleep(MICROSLEEP_LENGTH);
delayMicroseconds(MICROSLEEP_LENGTH);
#else
select();
SPI.transfer(addr | 0x80);
Expand Down
31 changes: 18 additions & 13 deletions piGateway/rfm69.h
Expand Up @@ -3,7 +3,7 @@
// **********************************************************************************
// Copyright Felix Rusu (2014), felix@lowpowerlab.com
// http://lowpowerlab.com/
// Raspberry Pi port by Alexandre Bouillot (2014) @abouillot on twitter
// Raspberry Pi port by Alexandre Bouillot (2014-2015) @abouillot on twitter
// **********************************************************************************
// License
// **********************************************************************************
Expand Down Expand Up @@ -84,6 +84,10 @@
#define RF69_TX_LIMIT_MS 1000
#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 {
public:
static volatile uint8_t DATA[RF69_MAX_DATA_LEN]; // recv/xmit buf, including header & crc bytes
Expand Down Expand Up @@ -111,20 +115,20 @@ class RFM69 {
void setAddress(uint8_t addr);
void setNetwork(uint8_t networkID);
bool canSend();
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
bool receiveDone();
virtual void send(uint8_t toAddress, const void* buffer, uint8_t bufferSize, bool requestACK=false);
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
virtual bool receiveDone();
bool ACKReceived(uint8_t fromNodeID);
bool ACKRequested();
void sendACK(const void* buffer = "", uint8_t bufferSize=0);
virtual void sendACK(const void* buffer = "", uint8_t bufferSize=0);
uint32_t getFrequency();
void setFrequency(uint32_t freqHz);
void encrypt(const char* key);
void setCS(uint8_t newSPISlaveSelect);
int16_t readRSSI(bool forceTrigger=false);
void promiscuous(bool onOff=true);
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 setHighPower(bool onOFF=true); // has to be called after initialize() for RFM69HW
virtual void setPowerLevel(uint8_t level); // reduce/increase transmit power level
void sleep();
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]
Expand All @@ -137,7 +141,8 @@ class RFM69 {
protected:
static void isr0();
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;
uint8_t _slaveSelectPin;
Expand All @@ -150,11 +155,11 @@ class RFM69 {
uint8_t _SPCR;
uint8_t _SPSR;

void receiveBegin();
void setMode(uint8_t mode);
void setHighPowerRegs(bool onOff);
void select();
void unselect();
virtual void receiveBegin();
virtual void setMode(uint8_t mode);
virtual void setHighPowerRegs(bool onOff);
virtual void select();
virtual void unselect();
};

#endif

0 comments on commit 51cbb29

Please sign in to comment.