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);
_address = nodeID;
_networkID = networkID;
#if defined(RF69_LISTENMODE_ENABLE)
selfPointer = this;
_freqBand = freqBand;
_networkID = networkID;
#endif
return true;
}
uint8_t RFM69::getVersion() {
return readReg(REG_VERSION);
}
// return the frequency (in Hz)
uint32_t RFM69::getFrequency() {
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);
}
// 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) {
if (newMode == _mode)
return;
@ -210,14 +223,23 @@ void RFM69::sleep() {
// set this node's address
void RFM69::setAddress(uint16_t 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
void RFM69::setNetwork(uint8_t networkID) {
_networkID = networkID;
writeReg(REG_SYNCVALUE2, networkID);
}
uint8_t RFM69::getNetwork() {
return _networkID;
}
// set user's ISR callback
void RFM69::setIsrCallback(void (*callback)()) {
_isrCallback = callback;
@ -263,8 +285,38 @@ void RFM69::setPowerLevel(uint8_t powerLevel) {
writeReg(REG_PALEVEL, PA_SETTING | powerLevel);
}
// return stored _powerLevel
uint8_t RFM69::getPowerLevel() { return _powerLevel; }
uint8_t RFM69::getOutputPower() {
// _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:
// [-18..+13]dBm in RFM69 W/CW
@ -287,6 +339,10 @@ int8_t RFM69::setPowerDBm(int8_t dBm) {
return dBm;
}
double RFM69::dBm_to_mW(uint8_t dBm) {
return pow(10, (dBm / 10.0));
}
bool RFM69::canSend() {
if (_mode == RF69_MODE_RX && PAYLOADLEN == 0 && readRSSI() < CSMA_LIMIT) { // if signal stronger than -100dBm is detected assume channel activity
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));
}
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
void RFM69::setHighPower(bool _isRFM69HW_HCW) {
_isRFM69HW = _isRFM69HW_HCW;
@ -575,6 +651,10 @@ void RFM69::setHighPower(bool _isRFM69HW_HCW) {
setPowerLevel(_powerLevel);
}
bool RFM69::isHighPower() {
return _isRFM69HW;
}
// internal function - for HW/HCW only:
// enables HiPower for 18-20dBm output
// should only be used with PA1+PA2

20
RFM69.h
View File

@ -163,6 +163,7 @@
#define RF69_BROADCAST_ADDR 0
#define RF69_CSMA_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)
// 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);
bool initialize(uint8_t freqBand, uint16_t ID, uint8_t networkID=1);
uint8_t getVersion();
uint16_t getAddress();
void setAddress(uint16_t addr);
uint8_t getNetwork();
void setNetwork(uint8_t networkID);
void setIsrCallback(void (*callback)());
virtual bool canSend();
@ -213,17 +217,27 @@ class RFM69 {
virtual void sendACK(const void* buffer = "", uint8_t bufferSize=0);
uint32_t getFrequency();
void setFrequency(uint32_t freqHz);
uint32_t getFrequencyDeviation();
uint32_t getBitRate();
void encrypt(const char* key);
void setCS(uint8_t newSPISlaveSelect);
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
bool getSpyMode();
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
bool isHighPower();
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
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();
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]
@ -258,6 +272,7 @@ class RFM69 {
uint8_t _interruptPin;
uint8_t _interruptNum;
uint16_t _address;
uint8_t _networkID;
bool _spyMode;
uint8_t _powerLevel;
bool _isRFM69HW;
@ -319,7 +334,6 @@ class RFM69 {
// Save these so we can reinitialize the radio after sending a burst
// or exiting listen mode.
uint8_t _freqBand;
uint8_t _networkID;
uint8_t _rxListenCoef;
uint8_t _rxListenResolution;
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
}
int16_t RFM69_ATC::getTargetRssi() {
return _targetRSSI;
}
//=============================================================================
// 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);
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
int16_t getTargetRssi();
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