From 07c3e9ed162a68df74c55d536e34da7e07efc9fe Mon Sep 17 00:00:00 2001 From: Auri Date: Tue, 2 Jun 2020 13:27:30 +0200 Subject: [PATCH 1/5] Custom SPI support --- RFM69.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/RFM69.h b/RFM69.h index 8673372..5cde615 100644 --- a/RFM69.h +++ b/RFM69.h @@ -197,7 +197,7 @@ class RFM69 { RFM69(uint8_t slaveSelectPin, uint8_t interruptPin, bool isRFM69HW, uint8_t interruptNum) //interruptNum is now deprecated : RFM69(slaveSelectPin, interruptPin, isRFM69HW){}; - RFM69(uint8_t slaveSelectPin=RF69_SPI_CS, uint8_t interruptPin=RF69_IRQ_PIN, bool isRFM69HW=false); + RFM69(uint8_t slaveSelectPin=RF69_SPI_CS, uint8_t interruptPin=RF69_IRQ_PIN, bool isRFM69HW=false, SPIClass *spi=nullptr); bool initialize(uint8_t freqBand, uint16_t ID, uint8_t networkID=1); void setAddress(uint16_t addr); @@ -249,6 +249,7 @@ class RFM69 { bool _spyMode; uint8_t _powerLevel; bool _isRFM69HW; + SPIClass *_spi; #if defined (SPCR) && defined (SPSR) uint8_t _SPCR; uint8_t _SPSR; @@ -314,4 +315,4 @@ class RFM69 { #endif }; -#endif \ No newline at end of file +#endif From 78447f61efaf3ab1d6b576e7c0f805385c012a56 Mon Sep 17 00:00:00 2001 From: Auri Date: Tue, 2 Jun 2020 13:43:09 +0200 Subject: [PATCH 2/5] Custom SPI support --- RFM69.cpp | 98 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 51 insertions(+), 47 deletions(-) diff --git a/RFM69.cpp b/RFM69.cpp index 259d9cd..154a537 100644 --- a/RFM69.cpp +++ b/RFM69.cpp @@ -41,7 +41,7 @@ uint8_t RFM69::ACK_RECEIVED; // should be polled immediately after sending a pac int16_t RFM69::RSSI; // most accurate RSSI during reception (closest to the reception) volatile bool RFM69::_haveData; -RFM69::RFM69(uint8_t slaveSelectPin, uint8_t interruptPin, bool isRFM69HW) +RFM69::RFM69(uint8_t slaveSelectPin, uint8_t interruptPin, bool isRFM69HW, SPIClass *spi) { _slaveSelectPin = slaveSelectPin; _interruptPin = interruptPin; @@ -49,6 +49,7 @@ RFM69::RFM69(uint8_t slaveSelectPin, uint8_t interruptPin, bool isRFM69HW) _spyMode = false; _powerLevel = 31; _isRFM69HW = isRFM69HW; + _spi = spi; #if defined(RF69_LISTENMODE_ENABLE) _isHighSpeed = true; _haveEncryptKey = false; @@ -111,13 +112,16 @@ bool RFM69::initialize(uint8_t freqBand, uint16_t nodeID, uint8_t networkID) digitalWrite(_slaveSelectPin, HIGH); pinMode(_slaveSelectPin, OUTPUT); + if(_spi == nullptr){ + _spi = &SPI; + } #if defined(ESP32) - SPI.begin(18,19,23,5); //SPI3 (SCK,MISO,MOSI,CS) - //SPI.begin(14,12,13,15); //SPI2 (SCK,MISO,MOSI,CS) + _spi->begin(18,19,23,5); //SPI3 (SCK,MISO,MOSI,CS) + //_spi->begin(14,12,13,15); //SPI2 (SCK,MISO,MOSI,CS) #else - SPI.begin(); -#endif - + _spi->begin(); +#endif + #ifdef SPI_HAS_TRANSACTION _settings = SPISettings(8000000, MSBFIRST, SPI_MODE0); #endif @@ -325,14 +329,14 @@ void RFM69::sendFrame(uint16_t toAddress, const void* buffer, uint8_t bufferSize // write to FIFO select(); - SPI.transfer(REG_FIFO | 0x80); - SPI.transfer(bufferSize + 3); - SPI.transfer((uint8_t)toAddress); - SPI.transfer((uint8_t)_address); - SPI.transfer(CTLbyte); + _spi->transfer(REG_FIFO | 0x80); + _spi->transfer(bufferSize + 3); + _spi->transfer((uint8_t)toAddress); + _spi->transfer((uint8_t)_address); + _spi->transfer(CTLbyte); for (uint8_t i = 0; i < bufferSize; i++) - SPI.transfer(((uint8_t*) buffer)[i]); + _spi->transfer(((uint8_t*) buffer)[i]); unselect(); // no need to wait for transmit mode to be ready since its handled by the radio @@ -349,12 +353,12 @@ void RFM69::interruptHandler() { { setMode(RF69_MODE_STANDBY); select(); - SPI.transfer(REG_FIFO & 0x7F); - PAYLOADLEN = SPI.transfer(0); + _spi->transfer(REG_FIFO & 0x7F); + PAYLOADLEN = _spi->transfer(0); PAYLOADLEN = PAYLOADLEN > 66 ? 66 : PAYLOADLEN; // precaution - TARGETID = SPI.transfer(0); - SENDERID = SPI.transfer(0); - uint8_t CTLbyte = SPI.transfer(0); + TARGETID = _spi->transfer(0); + SENDERID = _spi->transfer(0); + uint8_t CTLbyte = _spi->transfer(0); TARGETID |= (uint16_t(CTLbyte) & 0x0C) << 6; //10 bit address (most significant 2 bits stored in bits(2,3) of CTL byte SENDERID |= (uint16_t(CTLbyte) & 0x03) << 8; //10 bit address (most sifnigicant 2 bits stored in bits(0,1) of CTL byte @@ -372,7 +376,7 @@ void RFM69::interruptHandler() { 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); + for (uint8_t i = 0; i < DATALEN; i++) DATA[i] = _spi->transfer(0); DATA[DATALEN] = 0; // add null at end of string // add null at end of string unselect(); @@ -435,9 +439,9 @@ void RFM69::encrypt(const char* key) { memcpy(_encryptKey, key, 16); #endif select(); - SPI.transfer(REG_AESKEY1 | 0x80); + _spi->transfer(REG_AESKEY1 | 0x80); for (uint8_t i = 0; i < 16; i++) - SPI.transfer(key[i]); + _spi->transfer(key[i]); unselect(); } writeReg(REG_PACKETCONFIG2, (readReg(REG_PACKETCONFIG2) & 0xFE) | (key ? 1 : 0)); @@ -460,8 +464,8 @@ int16_t RFM69::readRSSI(bool forceTrigger) { uint8_t RFM69::readReg(uint8_t addr) { select(); - SPI.transfer(addr & 0x7F); - uint8_t regval = SPI.transfer(0); + _spi->transfer(addr & 0x7F); + uint8_t regval = _spi->transfer(0); unselect(); return regval; } @@ -469,8 +473,8 @@ uint8_t RFM69::readReg(uint8_t addr) void RFM69::writeReg(uint8_t addr, uint8_t value) { select(); - SPI.transfer(addr | 0x80); - SPI.transfer(value); + _spi->transfer(addr | 0x80); + _spi->transfer(value); unselect(); } @@ -483,15 +487,15 @@ void RFM69::select() { #endif #ifdef SPI_HAS_TRANSACTION - SPI.beginTransaction(_settings); + _spi->beginTransaction(_settings); #else // set RFM69 SPI settings explicitly - SPI.setDataMode(SPI_MODE0); - SPI.setBitOrder(MSBFIRST); + _spi->setDataMode(SPI_MODE0); + _spi->setBitOrder(MSBFIRST); #ifdef defined(__SAMD51__) - SPI.setClockDivider(SPI_CLOCK_DIV16); + _spi->setClockDivider(SPI_CLOCK_DIV16); #else - SPI.setClockDivider(SPI_CLOCK_DIV2); + _spi->setClockDivider(SPI_CLOCK_DIV2); #endif #endif digitalWrite(_slaveSelectPin, LOW); @@ -501,7 +505,7 @@ void RFM69::select() { void RFM69::unselect() { digitalWrite(_slaveSelectPin, HIGH); #ifdef SPI_HAS_TRANSACTION - SPI.endTransaction(); + _spi->endTransaction(); #endif // restore SPI settings to what they were before talking to RFM69 #if defined (SPCR) && defined (SPSR) @@ -573,8 +577,8 @@ void RFM69::readAllRegs() for (uint8_t regAddr = 1; regAddr <= 0x4F; regAddr++) { select(); - SPI.transfer(regAddr & 0x7F); // send address + r/w bit - regVal = SPI.transfer(0); + _spi->transfer(regAddr & 0x7F); // send address + r/w bit + regVal = _spi->transfer(0); unselect(); Serial.print(regAddr, HEX); @@ -1053,10 +1057,10 @@ void RFM69::listenModeInterruptHandler(void) burstRemaining.l = 0; - SPI.transfer(REG_FIFO & 0x7F); - PAYLOADLEN = SPI.transfer(0); + _spi->transfer(REG_FIFO & 0x7F); + PAYLOADLEN = _spi->transfer(0); PAYLOADLEN = PAYLOADLEN > 64 ? 64 : PAYLOADLEN; // precaution - TARGETID = SPI.transfer(0); + TARGETID = _spi->transfer(0); if(!(_spyMode || TARGETID == _address || TARGETID == RF69_BROADCAST_ADDR) // match this node's address, or broadcast address or anything in spy mode || PAYLOADLEN < 3) // address situation could receive packets that are malformed and don't fit this library's extra fields { @@ -1066,13 +1070,13 @@ void RFM69::listenModeInterruptHandler(void) // We've read the target, and will read the sender id and two time offset bytes for a total of 4 bytes DATALEN = PAYLOADLEN - 4; - SENDERID = SPI.transfer(0); - burstRemaining.b[0] = SPI.transfer(0); // and get the time remaining - burstRemaining.b[1] = SPI.transfer(0); + SENDERID = spi->transfer(0); + burstRemaining.b[0] = _spi->transfer(0); // and get the time remaining + burstRemaining.b[1] = _spi->transfer(0); RF69_LISTEN_BURST_REMAINING_MS = burstRemaining.l; for (uint8_t i = 0; i < DATALEN; i++) - DATA[i] = SPI.transfer(0); + DATA[i] = _spi->transfer(0); if (DATALEN < RF69_MAX_DATA_LEN) DATA[DATALEN] = 0; // add null at end of string @@ -1179,17 +1183,17 @@ void RFM69::listenModeSendBurst( uint8_t targetNode, const void* buffer, uint8_t noInterrupts(); // write to FIFO select(); - SPI.transfer(REG_FIFO | 0x80); - SPI.transfer(size + 4); // two bytes for target and sender node, two bytes for the burst time remaining - SPI.transfer(targetNode); - SPI.transfer(_address); + _spi->transfer(REG_FIFO | 0x80); + _spi->transfer(size + 4); // two bytes for target and sender node, two bytes for the burst time remaining + _spi->transfer(targetNode); + _spi->transfer(_address); // We send the burst time remaining with the packet so the receiver knows how long to wait before trying to reply - SPI.transfer(timeRemaining.b[0]); - SPI.transfer(timeRemaining.b[1]); + _spi->transfer(timeRemaining.b[0]); + _spi->transfer(timeRemaining.b[1]); for (uint8_t i = 0; i < size; i++) { - SPI.transfer(((uint8_t*) buffer)[i]); + _spi->transfer(((uint8_t*) buffer)[i]); } unselect(); @@ -1202,4 +1206,4 @@ void RFM69::listenModeSendBurst( uint8_t targetNode, const void* buffer, uint8_t setMode(RF69_MODE_STANDBY); reinitRadio(); } -#endif \ No newline at end of file +#endif From 06d2786f77b3a50014ff263a9cf306084d449f1e Mon Sep 17 00:00:00 2001 From: Auri Date: Tue, 2 Jun 2020 13:46:46 +0200 Subject: [PATCH 3/5] Custom SPI support --- RFM69_ATC.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RFM69_ATC.h b/RFM69_ATC.h index 05e2705..46e9044 100644 --- a/RFM69_ATC.h +++ b/RFM69_ATC.h @@ -36,8 +36,8 @@ class RFM69_ATC: public RFM69 { public: static volatile uint8_t ACK_RSSI_REQUESTED; // new flag in CTL byte to request RSSI with ACK (could potentially be merged with ACK_REQUESTED) - RFM69_ATC(uint8_t slaveSelectPin=RF69_SPI_CS, uint8_t interruptPin=RF69_IRQ_PIN, bool isRFM69HW=false, uint8_t interruptNum=0) : - RFM69(slaveSelectPin, interruptPin, isRFM69HW) { + RFM69_ATC(uint8_t slaveSelectPin=RF69_SPI_CS, uint8_t interruptPin=RF69_IRQ_PIN, bool isRFM69HW=false, uint8_t interruptNum=0, SPIClass *spi=nullptr) : + RFM69(slaveSelectPin, interruptPin, isRFM69HW, spi) { } bool initialize(uint8_t freqBand, uint16_t ID, uint8_t networkID=1); @@ -66,4 +66,4 @@ class RFM69_ATC: public RFM69 { uint8_t _PA_Reg; // saved and derived PA control bits so we don't have to spend time reading back from SPI port }; -#endif \ No newline at end of file +#endif From da14a5ad50a84c244a016cda412363bf4aea760a Mon Sep 17 00:00:00 2001 From: Auri Date: Tue, 2 Jun 2020 13:50:30 +0200 Subject: [PATCH 4/5] Custom SPI support --- RFM69_ATC.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/RFM69_ATC.cpp b/RFM69_ATC.cpp index 4530441..62b1f73 100644 --- a/RFM69_ATC.cpp +++ b/RFM69_ATC.cpp @@ -99,29 +99,29 @@ void RFM69_ATC::sendFrame(uint16_t toAddress, const void* buffer, uint8_t buffer // write to FIFO select(); - SPI.transfer(REG_FIFO | 0x80); - SPI.transfer(bufferSize + 3); - SPI.transfer((uint8_t)toAddress); //lower 8bits - SPI.transfer((uint8_t)_address); //lower 8bits + _spi->transfer(REG_FIFO | 0x80); + _spi->transfer(bufferSize + 3); + _spi->transfer((uint8_t)toAddress); //lower 8bits + _spi->transfer((uint8_t)_address); //lower 8bits // CTL (control byte) uint8_t CTLbyte=0x0; if (toAddress > 0xFF) CTLbyte |= (toAddress & 0x300) >> 6; //assign last 2 bits of address if > 255 if (_address > 0xFF) CTLbyte |= (_address & 0x300) >> 8; //assign last 2 bits of address if > 255 if (sendACK) { // TomWS1: adding logic to return ACK_RSSI if requested - SPI.transfer(CTLbyte | RFM69_CTL_SENDACK | (sendRSSI?RFM69_CTL_RESERVE1:0)); // TomWS1 TODO: Replace with EXT1 + _spi->transfer(CTLbyte | RFM69_CTL_SENDACK | (sendRSSI?RFM69_CTL_RESERVE1:0)); // TomWS1 TODO: Replace with EXT1 if (sendRSSI) { - SPI.transfer(abs(lastRSSI)); //RSSI dBm is negative expected between [-100 .. -20], convert to positive and pass along as single extra header byte + _spi->transfer(abs(lastRSSI)); //RSSI dBm is negative expected between [-100 .. -20], convert to positive and pass along as single extra header byte bufferSize -=1; // account for the extra ACK-RSSI 'data' byte } } else if (requestACK) { // TODO: add logic to request ackRSSI with ACK - this is when both ends of a transmission would dial power down. May not work well for gateways in multi node networks - SPI.transfer(CTLbyte | (_targetRSSI ? RFM69_CTL_REQACK | RFM69_CTL_RESERVE1 : RFM69_CTL_REQACK)); + _spi->transfer(CTLbyte | (_targetRSSI ? RFM69_CTL_REQACK | RFM69_CTL_RESERVE1 : RFM69_CTL_REQACK)); } - else SPI.transfer(CTLbyte); + else _spi->transfer(CTLbyte); for (uint8_t i = 0; i < bufferSize; i++) - SPI.transfer(((uint8_t*) buffer)[i]); + _spi->transfer(((uint8_t*) buffer)[i]); unselect(); // no need to wait for transmit mode to be ready since its handled by the radio @@ -141,7 +141,7 @@ void RFM69_ATC::interruptHook(uint8_t CTLbyte) { if (ACK_RECEIVED && ACK_RSSI_REQUESTED) { // the next two bytes contain the ACK_RSSI (assuming the datalength is valid) if (DATALEN >= 1) { - _ackRSSI = -1 * SPI.transfer(0); //rssi was sent as single byte positive value, get the real value by * -1 + _ackRSSI = -1 * _spi->transfer(0); //rssi was sent as single byte positive value, get the real value by * -1 DATALEN -= 1; // and compensate data length accordingly // TomWS1: Now dither transmitLevel value (register update occurs later when transmitting); if (_targetRSSI != 0) { @@ -277,4 +277,4 @@ byte RFM69_ATC::setLNA(byte newReg) { // TomWS1: New method used to disable LNA oldReg = readReg(REG_LNA); writeReg(REG_LNA, ((newReg & 7) | (oldReg & ~7))); // just control the LNA Gain bits for now return oldReg; // return the original value in case we need to restore it -} \ No newline at end of file +} From a4312f0a05184d24fe41466d08c69006450b6e5e Mon Sep 17 00:00:00 2001 From: Auri Date: Tue, 2 Jun 2020 13:57:16 +0200 Subject: [PATCH 5/5] Custom SPI support --- RFM69_ATC.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RFM69_ATC.h b/RFM69_ATC.h index 46e9044..99ae95a 100644 --- a/RFM69_ATC.h +++ b/RFM69_ATC.h @@ -36,7 +36,7 @@ class RFM69_ATC: public RFM69 { public: static volatile uint8_t ACK_RSSI_REQUESTED; // new flag in CTL byte to request RSSI with ACK (could potentially be merged with ACK_REQUESTED) - RFM69_ATC(uint8_t slaveSelectPin=RF69_SPI_CS, uint8_t interruptPin=RF69_IRQ_PIN, bool isRFM69HW=false, uint8_t interruptNum=0, SPIClass *spi=nullptr) : + RFM69_ATC(uint8_t slaveSelectPin=RF69_SPI_CS, uint8_t interruptPin=RF69_IRQ_PIN, bool isRFM69HW=false, SPIClass *spi=nullptr) : RFM69(slaveSelectPin, interruptPin, isRFM69HW, spi) { }