Add new getter functions to RFM69 and RFM69 ATC

- getVersion() to read RFM version
- getAddress() to return configured node ID
- getNetwork() to return configured network ID
- getFrequencyDeviation() to read frequency deviation
- getBitRate() to read the modulation bitrate in bits/second
- getSpyMode() to return spy mode setting
- isSyncOn()
- getSyncSize()
- isCrcOn() to check if CRC is activated
- isAesOn() to check if encryption is enabled
- isHighPower() to check if module is configured as HCW or not
- dBm_to_mW() to convert dBm to mW
- getOutputPower() to get the configured output power instead of returning the last set value
- getTargetRssi() to get the configured RSSI value, only for RFM69_ATC
- `_networkID` made public to get it via getNetwork() function
This commit is contained in:
Jonas Scharpf 2025-01-03 15:12:16 +01:00
parent ba99d94215
commit 2021234261
4 changed files with 111 additions and 12 deletions

View File

@ -140,14 +140,18 @@ bool RFM69::initialize(uint8_t freqBand, uint16_t nodeID, uint8_t networkID) {
attachInterrupt(_interruptNum, RFM69::isr0, RISING); attachInterrupt(_interruptNum, RFM69::isr0, RISING);
_address = nodeID; _address = nodeID;
_networkID = networkID;
#if defined(RF69_LISTENMODE_ENABLE) #if defined(RF69_LISTENMODE_ENABLE)
selfPointer = this; selfPointer = this;
_freqBand = freqBand; _freqBand = freqBand;
_networkID = networkID;
#endif #endif
return true; return true;
} }
uint8_t RFM69::getVersion() {
return readReg(REG_VERSION);
}
// return the frequency (in Hz) // return the frequency (in Hz)
uint32_t RFM69::getFrequency() { uint32_t RFM69::getFrequency() {
return RF69_FSTEP * (((uint32_t) readReg(REG_FRFMSB) << 16) + ((uint16_t) readReg(REG_FRFMID) << 8) + readReg(REG_FRFLSB)); return RF69_FSTEP * (((uint32_t) readReg(REG_FRFMSB) << 16) + ((uint16_t) readReg(REG_FRFMID) << 8) + readReg(REG_FRFLSB));
@ -169,6 +173,15 @@ void RFM69::setFrequency(uint32_t freqHz) {
setMode(oldMode); setMode(oldMode);
} }
// return the frequency deviation (in Hz)
uint32_t RFM69::getFrequencyDeviation() {
return RF69_FSTEP * ((readReg(REG_FDEVMSB) << 8) | readReg(REG_FDEVLSB));
}
uint32_t RFM69::getBitRate() {
return RF69_FXOSC / ((readReg(REG_BITRATEMSB) << 8) | readReg(REG_BITRATELSB));
}
void RFM69::setMode(uint8_t newMode) { void RFM69::setMode(uint8_t newMode) {
if (newMode == _mode) if (newMode == _mode)
return; return;
@ -210,14 +223,23 @@ void RFM69::sleep() {
// set this node's address // set this node's address
void RFM69::setAddress(uint16_t addr) { void RFM69::setAddress(uint16_t addr) {
_address = addr; _address = addr;
writeReg(REG_NODEADRS, _address); //unused in packet mode writeReg(REG_NODEADRS, _address); // unused in packet mode
}
uint16_t RFM69::getAddress() {
return _address;
} }
// set this node's network id // set this node's network id
void RFM69::setNetwork(uint8_t networkID) { void RFM69::setNetwork(uint8_t networkID) {
_networkID = networkID;
writeReg(REG_SYNCVALUE2, networkID); writeReg(REG_SYNCVALUE2, networkID);
} }
uint8_t RFM69::getNetwork() {
return _networkID;
}
// set user's ISR callback // set user's ISR callback
void RFM69::setIsrCallback(void (*callback)()) { void RFM69::setIsrCallback(void (*callback)()) {
_isrCallback = callback; _isrCallback = callback;
@ -263,8 +285,38 @@ void RFM69::setPowerLevel(uint8_t powerLevel) {
writeReg(REG_PALEVEL, PA_SETTING | powerLevel); writeReg(REG_PALEVEL, PA_SETTING | powerLevel);
} }
// return stored _powerLevel uint8_t RFM69::getOutputPower() {
uint8_t RFM69::getPowerLevel() { return _powerLevel; } // _RegisterBits(_REG_PA_LEVEL, offset=0, bits=5)
return readReg(REG_PALEVEL) & 0x1F;
}
uint8_t RFM69::getPowerLevel() {
uint8_t val = readReg(REG_PALEVEL);
uint8_t outputPower = getOutputPower();
bool pa0 = (val & 0b10000000) > 0;
bool pa1 = (val & 0b01000000) > 0;
bool pa2 = (val & 0b00100000) > 0;
if (pa0 && !pa1 && !pa2) {
// -18 to 13 dBm range
return -18 + outputPower;
}
if (!pa0 && pa1 && !pa2) {
// -2 to 13 dBm range
return -18 + outputPower;
}
if (!pa0 && pa1 && pa2 && !_isRFM69HW) {
// 2 to 17 dBm range
return -14 + outputPower;
}
if (!pa0 && pa1 && pa2 && _isRFM69HW) {
// 5 to 20 dBm range
return -11 + outputPower;
}
return 255;
}
// Set TX Output power in dBm: // Set TX Output power in dBm:
// [-18..+13]dBm in RFM69 W/CW // [-18..+13]dBm in RFM69 W/CW
@ -287,6 +339,10 @@ int8_t RFM69::setPowerDBm(int8_t dBm) {
return dBm; return dBm;
} }
double RFM69::dBm_to_mW(uint8_t dBm) {
return pow(10, (dBm / 10.0));
}
bool RFM69::canSend() { bool RFM69::canSend() {
if (_mode == RF69_MODE_RX && PAYLOADLEN == 0 && readRSSI() < CSMA_LIMIT) { // if signal stronger than -100dBm is detected assume channel activity if (_mode == RF69_MODE_RX && PAYLOADLEN == 0 && readRSSI() < CSMA_LIMIT) { // if signal stronger than -100dBm is detected assume channel activity
setMode(RF69_MODE_STANDBY); setMode(RF69_MODE_STANDBY);
@ -568,6 +624,26 @@ void RFM69::spyMode(bool onOff) {
//writeReg(REG_PACKETCONFIG1, (readReg(REG_PACKETCONFIG1) & 0xF9) | (onOff ? RF_PACKET1_ADRSFILTERING_OFF : RF_PACKET1_ADRSFILTERING_NODEBROADCAST)); //writeReg(REG_PACKETCONFIG1, (readReg(REG_PACKETCONFIG1) & 0xF9) | (onOff ? RF_PACKET1_ADRSFILTERING_OFF : RF_PACKET1_ADRSFILTERING_NODEBROADCAST));
} }
bool RFM69::getSpyMode() {
return _spyMode;
}
bool RFM69::isSyncOn() {
return readReg(REG_SYNCCONFIG) >> 7;
}
uint8_t RFM69::getSyncSize() {
return (readReg(REG_SYNCCONFIG) & 0b00111000) >> 3;
}
bool RFM69::isCrcOn() {
return (readReg(REG_PACKETCONFIG1) & 0b00010000) >> 4;
}
bool RFM69::isAesOn() {
return readReg(REG_PACKETCONFIG2) & 0b00000001;
}
// for RFM69 HW/HCW only: you must call setHighPower(true) after initialize() or else transmission won't work // for RFM69 HW/HCW only: you must call setHighPower(true) after initialize() or else transmission won't work
void RFM69::setHighPower(bool _isRFM69HW_HCW) { void RFM69::setHighPower(bool _isRFM69HW_HCW) {
_isRFM69HW = _isRFM69HW_HCW; _isRFM69HW = _isRFM69HW_HCW;
@ -575,6 +651,10 @@ void RFM69::setHighPower(bool _isRFM69HW_HCW) {
setPowerLevel(_powerLevel); setPowerLevel(_powerLevel);
} }
bool RFM69::isHighPower() {
return _isRFM69HW;
}
// internal function - for HW/HCW only: // internal function - for HW/HCW only:
// enables HiPower for 18-20dBm output // enables HiPower for 18-20dBm output
// should only be used with PA1+PA2 // should only be used with PA1+PA2

20
RFM69.h
View File

@ -163,6 +163,7 @@
#define RF69_BROADCAST_ADDR 0 #define RF69_BROADCAST_ADDR 0
#define RF69_CSMA_LIMIT_MS 1000 #define RF69_CSMA_LIMIT_MS 1000
#define RF69_TX_LIMIT_MS 1000 #define RF69_TX_LIMIT_MS 1000
#define RF69_FXOSC 32000000L
#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 // TWS: define CTLbyte bits
@ -201,7 +202,10 @@ class RFM69 {
RFM69(uint8_t slaveSelectPin=RF69_SPI_CS, uint8_t interruptPin=RF69_IRQ_PIN, bool isRFM69HW_HCW=false, SPIClass *spi=nullptr); RFM69(uint8_t slaveSelectPin=RF69_SPI_CS, uint8_t interruptPin=RF69_IRQ_PIN, bool isRFM69HW_HCW=false, SPIClass *spi=nullptr);
bool initialize(uint8_t freqBand, uint16_t ID, uint8_t networkID=1); bool initialize(uint8_t freqBand, uint16_t ID, uint8_t networkID=1);
uint8_t getVersion();
uint16_t getAddress();
void setAddress(uint16_t addr); void setAddress(uint16_t addr);
uint8_t getNetwork();
void setNetwork(uint8_t networkID); void setNetwork(uint8_t networkID);
void setIsrCallback(void (*callback)()); void setIsrCallback(void (*callback)());
virtual bool canSend(); virtual bool canSend();
@ -213,17 +217,27 @@ class RFM69 {
virtual 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);
uint32_t getFrequencyDeviation();
uint32_t getBitRate();
void encrypt(const char* key); void encrypt(const char* key);
void setCS(uint8_t newSPISlaveSelect); void setCS(uint8_t newSPISlaveSelect);
bool setIrq(uint8_t newIRQPin); bool setIrq(uint8_t newIRQPin);
int16_t readRSSI(bool forceTrigger=false); // *current* signal strength indicator; e.g. < -90dBm says the frequency channel is free + ready to transmit int16_t readRSSI(bool forceTrigger=false); // *current* signal strength indicator; e.g. < -90dBm says the frequency channel is free + ready to transmit
bool getSpyMode();
void spyMode(bool onOff=true); void spyMode(bool onOff=true);
//void promiscuous(bool onOff=true); //replaced with spyMode() bool isSyncOn();
uint8_t getSyncSize();
bool isCrcOn();
bool isAesOn();
//void promiscuous(bool onOff=true); // replaced with spyMode()
virtual void setHighPower(bool _isRFM69HW_HCW=true); // has to be called after initialize() for RFM69 HW/HCW virtual void setHighPower(bool _isRFM69HW_HCW=true); // has to be called after initialize() for RFM69 HW/HCW
bool isHighPower();
virtual void setPowerLevel(uint8_t level); // reduce/increase transmit power level virtual void setPowerLevel(uint8_t level); // reduce/increase transmit power level
virtual int8_t setPowerDBm(int8_t dBm); // reduce/increase transmit power level, in dBm virtual int8_t setPowerDBm(int8_t dBm); // reduce/increase transmit power level, in dBm
double dBm_to_mW(uint8_t dBm); // convert dBm to mW
virtual uint8_t getPowerLevel(); // get powerLevel uint8_t getOutputPower();
uint8_t getPowerLevel(); // get powerLevel
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]
@ -258,6 +272,7 @@ class RFM69 {
uint8_t _interruptPin; uint8_t _interruptPin;
uint8_t _interruptNum; uint8_t _interruptNum;
uint16_t _address; uint16_t _address;
uint8_t _networkID;
bool _spyMode; bool _spyMode;
uint8_t _powerLevel; uint8_t _powerLevel;
bool _isRFM69HW; bool _isRFM69HW;
@ -319,7 +334,6 @@ class RFM69 {
// Save these so we can reinitialize the radio after sending a burst // Save these so we can reinitialize the radio after sending a burst
// or exiting listen mode. // or exiting listen mode.
uint8_t _freqBand; uint8_t _freqBand;
uint8_t _networkID;
uint8_t _rxListenCoef; uint8_t _rxListenCoef;
uint8_t _rxListenResolution; uint8_t _rxListenResolution;
uint8_t _idleListenCoef; uint8_t _idleListenCoef;

View File

@ -174,6 +174,10 @@ void RFM69_ATC::enableAutoPower(int16_t targetRSSI){ // TomWS1: New method t
_targetRSSI = targetRSSI; // no logic here, just set the value (if non-zero, then enabled), caller's responsibility to use a reasonable value _targetRSSI = targetRSSI; // no logic here, just set the value (if non-zero, then enabled), caller's responsibility to use a reasonable value
} }
int16_t RFM69_ATC::getTargetRssi() {
return _targetRSSI;
}
//============================================================================= //=============================================================================
// getAckRSSI() - returns the RSSI value ack'd by the far end. // getAckRSSI() - returns the RSSI value ack'd by the far end.
//============================================================================= //=============================================================================

View File

@ -44,6 +44,7 @@ class RFM69_ATC: public RFM69 {
void sendACK(const void* buffer = "", uint8_t bufferSize=0); void sendACK(const void* buffer = "", uint8_t bufferSize=0);
bool sendWithRetry(uint16_t toAddress, const void* buffer, uint8_t bufferSize, uint8_t retries=2, uint8_t retryWaitTime=RFM69_ACK_TIMEOUT); bool sendWithRetry(uint16_t toAddress, const void* buffer, uint8_t bufferSize, uint8_t retries=2, uint8_t retryWaitTime=RFM69_ACK_TIMEOUT);
void enableAutoPower(int16_t targetRSSI=-90); // TWS: New method to enable/disable auto Power control void enableAutoPower(int16_t targetRSSI=-90); // TWS: New method to enable/disable auto Power control
int16_t getTargetRssi();
int16_t getAckRSSI(void); // TWS: New method to retrieve the ack'd RSSI (if any) int16_t getAckRSSI(void); // TWS: New method to retrieve the ack'd RSSI (if any)
int16_t _targetRSSI; // if non-zero then this is the desired end point RSSI for our transmission int16_t _targetRSSI; // if non-zero then this is the desired end point RSSI for our transmission