commit
b8b22cec79
92
RFM69.cpp
92
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,11 +112,14 @@ 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();
|
||||
_spi->begin();
|
||||
#endif
|
||||
|
||||
#ifdef SPI_HAS_TRANSACTION
|
||||
|
|
@ -330,14 +334,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
|
||||
|
|
@ -354,12 +358,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
|
||||
|
||||
|
|
@ -377,7 +381,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();
|
||||
|
|
@ -440,9 +444,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));
|
||||
|
|
@ -465,8 +469,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;
|
||||
}
|
||||
|
|
@ -474,8 +478,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();
|
||||
}
|
||||
|
||||
|
|
@ -488,15 +492,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);
|
||||
|
|
@ -506,7 +510,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)
|
||||
|
|
@ -578,8 +582,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);
|
||||
|
|
@ -1058,10 +1062,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
|
||||
{
|
||||
|
|
@ -1071,13 +1075,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
|
||||
|
|
@ -1184,17 +1188,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();
|
||||
|
|
|
|||
3
RFM69.h
3
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);
|
||||
|
|
@ -250,6 +250,7 @@ class RFM69 {
|
|||
bool _spyMode;
|
||||
uint8_t _powerLevel;
|
||||
bool _isRFM69HW;
|
||||
SPIClass *_spi;
|
||||
#if defined (SPCR) && defined (SPSR)
|
||||
uint8_t _SPCR;
|
||||
uint8_t _SPSR;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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, SPIClass *spi=nullptr) :
|
||||
RFM69(slaveSelectPin, interruptPin, isRFM69HW, spi) {
|
||||
}
|
||||
|
||||
bool initialize(uint8_t freqBand, uint16_t ID, uint8_t networkID=1);
|
||||
|
|
|
|||
Loading…
Reference in New Issue