diff --git a/src/TypeDef.h b/src/TypeDef.h index 0d250d50..e2d8c914 100644 --- a/src/TypeDef.h +++ b/src/TypeDef.h @@ -218,6 +218,11 @@ */ #define RADIOLIB_ERR_INVALID_RSSI_THRESHOLD (-27) +/*! + \brief A `NULL` pointer has been encountered. If you see this, there may be a potential security vulnerability. +*/ +#define RADIOLIB_ERR_NULL_POINTER (-28) + // RF69-specific status codes /*! diff --git a/src/modules/CC1101/CC1101.cpp b/src/modules/CC1101/CC1101.cpp index 5b44bc55..9407523b 100644 --- a/src/modules/CC1101/CC1101.cpp +++ b/src/modules/CC1101/CC1101.cpp @@ -89,7 +89,8 @@ int16_t CC1101::begin(float freq, float br, float freqDev, float rxBw, int8_t po RADIOLIB_ASSERT(state); // set default sync word - state = setSyncWord(0x12, 0xAD, 0, false); + uint8_t sw[RADIOLIB_CC1101_DEFAULT_SW_LEN] = RADIOLIB_CC1101_DEFAULT_SW; + state = setSyncWord(sw[0], sw[1], 0, false); RADIOLIB_ASSERT(state); // flush FIFOs @@ -472,7 +473,7 @@ int16_t CC1101::setBitRate(float br) { int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG4, e, 3, 0); state |= SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG3, m); if(state == RADIOLIB_ERR_NONE) { - CC1101::_br = br; + _br = br; } return(state); } @@ -491,6 +492,7 @@ int16_t CC1101::setRxBandwidth(float rxBw) { // set Rx channel filter bandwidth return(SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG4, (e << 6) | (m << 4), 7, 4)); } + } } @@ -517,9 +519,35 @@ int16_t CC1101::setFrequencyDeviation(float freqDev) { // set frequency deviation value int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_DEVIATN, (e << 4), 6, 4); state |= SPIsetRegValue(RADIOLIB_CC1101_REG_DEVIATN, m, 2, 0); + return(state); } +int16_t CC1101::getFrequencyDeviation(float *freqDev) { + if (freqDev == NULL) { + return(RADIOLIB_ERR_NULL_POINTER); + } + + // if ASK/OOK, deviation makes no sense + if (_modulation == RADIOLIB_CC1101_MOD_FORMAT_ASK_OOK) { + *freqDev = 0.0; + + return(RADIOLIB_ERR_NONE); + } + + // get exponent and mantissa values from registers + uint8_t e = (uint8_t)(SPIgetRegValue(RADIOLIB_CC1101_REG_DEVIATN, 6, 4) >> 4); + uint8_t m = (uint8_t)SPIgetRegValue(RADIOLIB_CC1101_REG_DEVIATN, 2, 0); + + // calculate frequency deviation (pag. 79 of the CC1101 datasheet): + // + // freqDev = (fXosc / 2^17) * (8 + m) * 2^e + // + *freqDev = (1000.0 / (uint32_t(1) << 17)) - (8 + m) * (uint32_t(1) << e); + + return(RADIOLIB_ERR_NONE); +} + int16_t CC1101::setOutputPower(int8_t power) { // round to the known frequency settings uint8_t f; @@ -608,8 +636,6 @@ int16_t CC1101::setSyncWord(uint8_t* syncWord, uint8_t len, uint8_t maxErrBits, } } - _syncWordLength = len; - // enable sync word filtering int16_t state = enableSyncWordFiltering(maxErrBits, requireCarrierSense); RADIOLIB_ASSERT(state); @@ -658,11 +684,9 @@ int16_t CC1101::setPreambleLength(uint8_t preambleLength) { return(RADIOLIB_ERR_INVALID_PREAMBLE_LENGTH); } - - return SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG1, value, 6, 4); + return(SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG1, value, 6, 4)); } - int16_t CC1101::setNodeAddress(uint8_t nodeAddr, uint8_t numBroadcastAddrs) { RADIOLIB_CHECK_RANGE(numBroadcastAddrs, 1, 2, RADIOLIB_ERR_INVALID_NUM_BROAD_ADDRS); diff --git a/src/modules/CC1101/CC1101.h b/src/modules/CC1101/CC1101.h index 3ae99b63..bb245cbe 100644 --- a/src/modules/CC1101/CC1101.h +++ b/src/modules/CC1101/CC1101.h @@ -499,6 +499,16 @@ #define RADIOLIB_CC1101_GDO2_ACTIVE 0b00000100 // 2 2 GDO2 is active/asserted #define RADIOLIB_CC1101_GDO0_ACTIVE 0b00000001 // 0 0 GDO0 is active/asserted +//Defaults +#define RADIOLIB_CC1101_DEFAULT_FREQ 434.0 +#define RADIOLIB_CC1101_DEFAULT_BR 4.8 +#define RADIOLIB_CC1101_DEFAULT_FREQDEV 5.0 +#define RADIOLIB_CC1101_DEFAULT_RXBW 135.0 +#define RADIOLIB_CC1101_DEFAULT_POWER 10 +#define RADIOLIB_CC1101_DEFAULT_PREAMBLELEN 16 +#define RADIOLIB_CC1101_DEFAULT_SW {0x12, 0xAD} +#define RADIOLIB_CC1101_DEFAULT_SW_LEN 2 + /*! \class CC1101 @@ -526,7 +536,7 @@ class CC1101: public PhysicalLayer { /*! \brief Initialization method. - \param freq Carrier frequency in MHz. Defaults to 434.0 MHz. + \param freq Carrier frequency in MHz. Defaults to 434 MHz. \param br Bit rate to be used in kbps. Defaults to 4.8 kbps. @@ -540,7 +550,13 @@ class CC1101: public PhysicalLayer { \returns \ref status_codes */ - int16_t begin(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 135.0, int8_t power = 10, uint8_t preambleLength = 16); + int16_t begin( + float freq = RADIOLIB_CC1101_DEFAULT_FREQ, + float br = RADIOLIB_CC1101_DEFAULT_BR, + float freqDev = RADIOLIB_CC1101_DEFAULT_FREQDEV, + float rxBw = RADIOLIB_CC1101_DEFAULT_RXBW, + int8_t power = RADIOLIB_CC1101_DEFAULT_POWER, + uint8_t preambleLength = RADIOLIB_CC1101_DEFAULT_PREAMBLELEN); /*! \brief Blocking binary transmit method. @@ -720,6 +736,15 @@ class CC1101: public PhysicalLayer { */ int16_t setFrequencyDeviation(float freqDev) override; + /*! + \brief Gets frequency deviation. + + \param[out] freqDev Pointer to variable where to save the frequency deviation. + + \returns \ref status_codes + */ + int16_t getFrequencyDeviation(float *freqDev); + /*! \brief Sets output power. Allowed values are -30, -20, -15, -10, 0, 5, 7 or 10 dBm. @@ -973,8 +998,8 @@ class CC1101: public PhysicalLayer { protected: #endif - float _freq = 0; - float _br = 0; + float _freq = RADIOLIB_CC1101_DEFAULT_FREQ; + float _br = RADIOLIB_CC1101_DEFAULT_BR; uint8_t _rawRSSI = 0; uint8_t _rawLQI = 0; uint8_t _modulation = RADIOLIB_CC1101_MOD_FORMAT_2_FSK; @@ -987,8 +1012,8 @@ class CC1101: public PhysicalLayer { bool _crcOn = true; bool _directMode = true; - uint8_t _syncWordLength = 2; - int8_t _power = 0; + int8_t _power = RADIOLIB_CC1101_DEFAULT_POWER; + int16_t config(); int16_t transmitDirect(bool sync, uint32_t frf); diff --git a/src/modules/RF69/RF69.cpp b/src/modules/RF69/RF69.cpp index 699bf16d..5cfd833a 100644 --- a/src/modules/RF69/RF69.cpp +++ b/src/modules/RF69/RF69.cpp @@ -59,7 +59,7 @@ int16_t RF69::begin(float freq, float br, float freqDev, float rxBw, int8_t powe RADIOLIB_ASSERT(state); // configure bitrate - _rxBw = 125.0; + _rxBw = rxBw; state = setBitRate(br); RADIOLIB_ASSERT(state); @@ -84,7 +84,7 @@ int16_t RF69::begin(float freq, float br, float freqDev, float rxBw, int8_t powe RADIOLIB_ASSERT(state); // set default sync word - uint8_t syncWord[] = {0x12, 0xAD}; + uint8_t syncWord[] = RADIOLIB_RF69_DEFAULT_SW; state = setSyncWord(syncWord, sizeof(syncWord)); RADIOLIB_ASSERT(state); @@ -526,12 +526,26 @@ int16_t RF69::setFrequency(float freq) { setMode(RADIOLIB_RF69_STANDBY); //set carrier frequency + //FRF(23:0) = freq / Fstep = freq * (1 / Fstep) = freq * (2^19 / 32.0) (pag. 17 of datasheet) uint32_t FRF = (freq * (uint32_t(1) << RADIOLIB_RF69_DIV_EXPONENT)) / RADIOLIB_RF69_CRYSTAL_FREQ; _mod->SPIwriteRegister(RADIOLIB_RF69_REG_FRF_MSB, (FRF & 0xFF0000) >> 16); _mod->SPIwriteRegister(RADIOLIB_RF69_REG_FRF_MID, (FRF & 0x00FF00) >> 8); _mod->SPIwriteRegister(RADIOLIB_RF69_REG_FRF_LSB, FRF & 0x0000FF); - _freq = freq; + return(RADIOLIB_ERR_NONE); +} + +int16_t RF69::getFrequency(float *freq) { + uint32_t FRF = 0; + + //FRF(23:0) = [ [FRF_MSB]|[FRF_MID]|[FRF_LSB]] + //FRF(32:0) = [0x00|[FRF_MSB]|[FRF_MID]|[FRF_LSB]] + FRF |= (((uint32_t)(_mod->SPIgetRegValue(RADIOLIB_RF69_REG_FRF_MSB, 7, 0)) << 16) & 0x00FF0000); + FRF |= (((uint32_t)(_mod->SPIgetRegValue(RADIOLIB_RF69_REG_FRF_MID, 7, 0)) << 8) & 0x0000FF00); + FRF |= (((uint32_t)(_mod->SPIgetRegValue(RADIOLIB_RF69_REG_FRF_LSB, 7, 0)) << 0) & 0x000000FF); + + //freq = Fstep * FRF(23:0) = (32.0 / 2^19) * FRF(23:0) (pag. 17 of datasheet) + *freq = FRF * ( RADIOLIB_RF69_CRYSTAL_FREQ / (uint32_t(1) << RADIOLIB_RF69_DIV_EXPONENT) ); return(RADIOLIB_ERR_NONE); } @@ -552,7 +566,7 @@ int16_t RF69::setBitRate(float br) { int16_t state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_BITRATE_MSB, (bitRate & 0xFF00) >> 8, 7, 0); state |= _mod->SPIsetRegValue(RADIOLIB_RF69_REG_BITRATE_LSB, bitRate & 0x00FF, 7, 0); if(state == RADIOLIB_ERR_NONE) { - RF69::_br = br; + _br = br; } return(state); } @@ -575,7 +589,7 @@ int16_t RF69::setRxBandwidth(float rxBw) { // set Rx bandwidth state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_RX_BW, (m << 3) | e, 4, 0); if(state == RADIOLIB_ERR_NONE) { - RF69::_rxBw = rxBw; + _rxBw = rxBw; } return(state); } @@ -601,14 +615,37 @@ int16_t RF69::setFrequencyDeviation(float freqDev) { setMode(RADIOLIB_RF69_STANDBY); // set frequency deviation from carrier frequency - uint32_t base = 1; - uint32_t fdev = (newFreqDev * (base << 19)) / 32000; + uint32_t fdev = (newFreqDev * (uint32_t(1) << RADIOLIB_RF69_DIV_EXPONENT)) / 32000; int16_t state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_FDEV_MSB, (fdev & 0xFF00) >> 8, 5, 0); state |= _mod->SPIsetRegValue(RADIOLIB_RF69_REG_FDEV_LSB, fdev & 0x00FF, 7, 0); return(state); } +int16_t RF69::getFrequencyDeviation(float *freqDev) { + if (freqDev == NULL) { + return(RADIOLIB_ERR_NULL_POINTER); + } + + if (RF69::_ook) { + *freqDev = 0.0; + + return(RADIOLIB_ERR_NONE); + } + + // get raw value from register + uint32_t fdev = 0; + fdev |= (uint32_t)((_mod->SPIgetRegValue(RADIOLIB_RF69_REG_FDEV_MSB, 5, 0) << 8) & 0x0000FF00); + fdev |= (uint32_t)((_mod->SPIgetRegValue(RADIOLIB_RF69_REG_FDEV_LSB, 7, 0) << 0) & 0x000000FF); + + // calculate frequency deviation from raw value obtained from register + // Fdev = Fstep * Fdev(13:0) (pag. 20 of datasheet) + *freqDev = (fdev * RADIOLIB_RF69_CRYSTAL_FREQ) / + (uint32_t(1) << RADIOLIB_RF69_DIV_EXPONENT); + + return(RADIOLIB_ERR_NONE); +} + int16_t RF69::setOutputPower(int8_t power, bool highPower) { if(highPower) { RADIOLIB_CHECK_RANGE(power, -2, 20, RADIOLIB_ERR_INVALID_OUTPUT_POWER); @@ -660,14 +697,17 @@ int16_t RF69::setSyncWord(uint8_t* syncWord, size_t len, uint8_t maxErrBits) { } } - _syncWordLength = len; - int16_t state = enableSyncWordFiltering(maxErrBits); RADIOLIB_ASSERT(state); // set sync word register _mod->SPIwriteRegisterBurst(RADIOLIB_RF69_REG_SYNC_VALUE_1, syncWord, len); - return(RADIOLIB_ERR_NONE); + + if(state == RADIOLIB_ERR_NONE) { + _syncWordLength = len; + } + + return(state); } int16_t RF69::setPreambleLength(uint8_t preambleLen) { @@ -678,7 +718,8 @@ int16_t RF69::setPreambleLength(uint8_t preambleLen) { uint8_t preLenBytes = preambleLen / 8; _mod->SPIwriteRegister(RADIOLIB_RF69_REG_PREAMBLE_MSB, 0x00); - return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_PREAMBLE_LSB, preLenBytes)); + + return (_mod->SPIsetRegValue(RADIOLIB_RF69_REG_PREAMBLE_LSB, preLenBytes)); } int16_t RF69::setNodeAddress(uint8_t nodeAddr) { @@ -819,6 +860,10 @@ int16_t RF69::setPromiscuousMode(bool promiscuous) { // enable CRC filtering state = setCrcFiltering(true); } + if(state == RADIOLIB_ERR_NONE) { + _promiscuous = promiscuous; + } + return(state); } diff --git a/src/modules/RF69/RF69.h b/src/modules/RF69/RF69.h index 9233f57a..7cb41d90 100644 --- a/src/modules/RF69/RF69.h +++ b/src/modules/RF69/RF69.h @@ -462,6 +462,15 @@ #define RADIOLIB_RF69_PA2_NORMAL 0x70 // 7 0 PA_BOOST: none #define RADIOLIB_RF69_PA2_20_DBM 0x7C // 7 0 +20 dBm +// Defaults +#define RADIOLIB_RF69_DEFAULT_FREQ 434.0 +#define RADIOLIB_RF69_DEFAULT_BR 4.8 +#define RADIOLIB_RF69_DEFAULT_FREQDEV 5.0 +#define RADIOLIB_RF69_DEFAULT_RXBW 125.0 +#define RADIOLIB_RF69_DEFAULT_POWER 10 +#define RADIOLIB_RF69_DEFAULT_PREAMBLELEN 16 +#define RADIOLIB_RF69_DEFAULT_SW {0x12, 0xAD} +#define RADIOLIB_RF69_DEFAULT_SW_LEN 2 /*! \class RF69 @@ -503,7 +512,13 @@ class RF69: public PhysicalLayer { \returns \ref status_codes */ - int16_t begin(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 125.0, int8_t power = 10, uint8_t preambleLen = 16); + int16_t begin( + float freq = RADIOLIB_RF69_DEFAULT_FREQ, + float br = RADIOLIB_RF69_DEFAULT_BR, + float freqDev = RADIOLIB_RF69_DEFAULT_FREQDEV, + float rxBw = RADIOLIB_RF69_DEFAULT_RXBW, + int8_t power = RADIOLIB_RF69_DEFAULT_POWER, + uint8_t preambleLen = RADIOLIB_RF69_DEFAULT_PREAMBLELEN); /*! \brief Reset method. Will reset the chip to the default state using RST pin. @@ -721,6 +736,15 @@ class RF69: public PhysicalLayer { */ int16_t setFrequency(float freq); + /*! + \brief Gets carrier frequency. + + \param[out] freq Variable to write carrier frequency currently set, in MHz. + + \returns \ref status_codes + */ + int16_t getFrequency(float *freq); + /*! \brief Sets bit rate. Allowed values range from 1.2 to 300.0 kbps. @@ -748,6 +772,15 @@ class RF69: public PhysicalLayer { */ int16_t setFrequencyDeviation(float freqDev) override; + /*! + \brief Gets frequency deviation. + + \param[out] freqDev Where to write the frequency deviation currently set, in kHz. + + \returns \ref status_codes + */ + int16_t getFrequencyDeviation(float *freqDev); + /*! \brief Sets output power. Allowed values range from -18 to 13 dBm for low power modules (RF69C/CW) or -2 to 20 dBm (RF69H/HC/HCW). @@ -1037,12 +1070,12 @@ class RF69: public PhysicalLayer { protected: #endif - float _freq = 0; - float _br = 0; - float _rxBw = 0; + float _freq = RADIOLIB_RF69_DEFAULT_FREQ; + float _br = RADIOLIB_RF69_DEFAULT_BR; + float _rxBw = RADIOLIB_RF69_DEFAULT_RXBW; bool _ook = false; int16_t _tempOffset = 0; - int8_t _power = 0; + int8_t _power = RADIOLIB_RF69_DEFAULT_POWER; size_t _packetLength = 0; bool _packetLengthQueried = false; @@ -1050,7 +1083,7 @@ class RF69: public PhysicalLayer { bool _promiscuous = false; - uint8_t _syncWordLength = 2; + uint8_t _syncWordLength = RADIOLIB_RF69_DEFAULT_SW_LEN; bool _bitSync = true; diff --git a/src/modules/nRF24/nRF24.cpp b/src/modules/nRF24/nRF24.cpp index 972eaff7..f00f42e3 100644 --- a/src/modules/nRF24/nRF24.cpp +++ b/src/modules/nRF24/nRF24.cpp @@ -254,7 +254,13 @@ int16_t nRF24::setFrequency(float freq) { // set frequency uint8_t freqRaw = (uint16_t)freq - 2400; - return(_mod->SPIsetRegValue(RADIOLIB_NRF24_REG_RF_CH, freqRaw, 6, 0)); + int16_t state = _mod->SPIsetRegValue(RADIOLIB_NRF24_REG_RF_CH, freqRaw, 6, 0); + + if(state == RADIOLIB_ERR_NONE) { + _freq = freq; + } + + return(state); } int16_t nRF24::setBitRate(float br) { @@ -276,6 +282,11 @@ int16_t nRF24::setBitRate(float br) { } else { return(RADIOLIB_ERR_INVALID_DATA_RATE); } + + if(state == RADIOLIB_ERR_NONE) { + _dataRate = dataRate; + } + return(state); } @@ -306,6 +317,12 @@ int16_t nRF24::setOutputPower(int8_t power) { // write new register value state = _mod->SPIsetRegValue(RADIOLIB_NRF24_REG_RF_SETUP, powerRaw, 2, 1); + + if(state == RADIOLIB_ERR_NONE) { + _power = power; + } + + return(state); } @@ -335,7 +352,9 @@ int16_t nRF24::setAddressWidth(uint8_t addrWidth) { } // save address width - _addrWidth = addrWidth; + if(state == RADIOLIB_ERR_NONE) { + _addrWidth = addrWidth; + } return(state); } diff --git a/src/modules/nRF24/nRF24.h b/src/modules/nRF24/nRF24.h index 3d4af395..72605c6f 100644 --- a/src/modules/nRF24/nRF24.h +++ b/src/modules/nRF24/nRF24.h @@ -171,6 +171,13 @@ #define RADIOLIB_NRF24_DYN_ACK_OFF 0b00000000 // 0 0 payloads without ACK: disabled (default) #define RADIOLIB_NRF24_DYN_ACK_ON 0b00000001 // 0 0 enabled +// Defaults +#define RADIOLIB_NRF24_DEFAULT_FREQ 2400 +#define RADIOLIB_NRF24_DEFAULT_DR 1000 +#define RADIOLIB_NRF24_DEFAULT_POWER -12 +#define RADIOLIB_NRF24_DEFAULT_ADDRWIDTH 5 + + /*! \class nRF24 @@ -208,7 +215,11 @@ class nRF24: public PhysicalLayer { \returns \ref status_codes */ - int16_t begin(int16_t freq = 2400, int16_t dataRate = 1000, int8_t power = -12, uint8_t addrWidth = 5); + int16_t begin( + int16_t freq = RADIOLIB_NRF24_DEFAULT_FREQ, + int16_t dataRate = RADIOLIB_NRF24_DEFAULT_DR, + int8_t power = RADIOLIB_NRF24_DEFAULT_POWER, + uint8_t addrWidth = RADIOLIB_NRF24_DEFAULT_ADDRWIDTH); /*! \brief Sets the module to sleep mode. @@ -509,7 +520,11 @@ class nRF24: public PhysicalLayer { protected: #endif - uint8_t _addrWidth = 0; + int16_t _freq = RADIOLIB_NRF24_DEFAULT_FREQ; + int16_t _dataRate = RADIOLIB_NRF24_DEFAULT_DR; + int8_t _power = RADIOLIB_NRF24_DEFAULT_POWER; + uint8_t _addrWidth = RADIOLIB_NRF24_DEFAULT_ADDRWIDTH; + int16_t config(); void clearIRQ();