diff --git a/examples/SX127x/SX127x_FSK_Modem/SX127x_FSK_Modem.ino b/examples/SX127x/SX127x_FSK_Modem/SX127x_FSK_Modem.ino index f9c89154..f9e2821d 100644 --- a/examples/SX127x/SX127x_FSK_Modem/SX127x_FSK_Modem.ino +++ b/examples/SX127x/SX127x_FSK_Modem/SX127x_FSK_Modem.ino @@ -38,7 +38,7 @@ void setup() { // Rx bandwidth: 125.0 kHz // output power: 13 dBm // current limit: 100 mA - // data shaping: Gaussian, BT = 0.3 + // data shaping: Gaussian, BT = 0.5 // sync word: 0x2D 0x01 // OOK modulation: disabled int state = fsk.beginFSK(); diff --git a/library.properties b/library.properties index 81829f5b..21975e9d 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=RadioLib -version=3.3.0 +version=3.4.0 author=Jan Gromes maintainer=Jan Gromes sentence=Universal wireless communication library for Arduino diff --git a/src/Module.cpp b/src/Module.cpp index bce8abd4..7a714d85 100644 --- a/src/Module.cpp +++ b/src/Module.cpp @@ -1,11 +1,34 @@ #include "Module.h" +Module::Module(int16_t cs, int16_t irq, int16_t rst) { + _cs = cs; + _rx = NC; + _tx = NC; + _irq = irq; + _rst = rst; + _spi = &SPI; + _spiSettings = SPISettings(2000000, MSBFIRST, SPI_MODE0); + _initInterface = true; +} + +Module::Module(int16_t cs, int16_t irq, int16_t rst, int16_t gpio) { + _cs = cs; + _rx = gpio; + _tx = NC; + _irq = irq; + _rst = rst; + _spi = &SPI; + _spiSettings = SPISettings(2000000, MSBFIRST, SPI_MODE0); + _initInterface = true; +} + Module::Module(int16_t rx, int16_t tx, HardwareSerial* useSer, int16_t rst) { _cs = NC; _rx = rx; _tx = tx; _irq = NC; _rst = rst; + _initInterface = true; #ifdef RADIOLIB_SOFTWARE_SERIAL_UNSUPPORTED ModuleSerial = useSer; @@ -23,6 +46,7 @@ Module::Module(int16_t cs, int16_t irq, int16_t rst, SPIClass& spi, SPISettings _rst = rst; _spi = &spi; _spiSettings = spiSettings; + _initInterface = false; } Module::Module(int16_t cs, int16_t irq, int16_t rst, int16_t gpio, SPIClass& spi, SPISettings spiSettings) { @@ -33,6 +57,7 @@ Module::Module(int16_t cs, int16_t irq, int16_t rst, int16_t gpio, SPIClass& spi _rst = rst; _spi = &spi; _spiSettings = spiSettings; + _initInterface = false; } Module::Module(int16_t cs, int16_t irq, int16_t rst, int16_t rx, int16_t tx, SPIClass& spi, SPISettings spiSettings, HardwareSerial* useSer) { @@ -43,6 +68,7 @@ Module::Module(int16_t cs, int16_t irq, int16_t rst, int16_t rx, int16_t tx, SPI _rst = rst; _spi = &spi; _spiSettings = spiSettings; + _initInterface = false; #ifdef RADIOLIB_SOFTWARE_SERIAL_UNSUPPORTED ModuleSerial = useSer; @@ -58,14 +84,18 @@ void Module::init(uint8_t interface) { case RADIOLIB_USE_SPI: Module::pinMode(_cs, OUTPUT); Module::digitalWrite(_cs, HIGH); - _spi->begin(); + if(_initInterface) { + _spi->begin(); + } break; case RADIOLIB_USE_UART: + if(_initInterface) { #if defined(ESP32) - ModuleSerial->begin(baudrate, SERIAL_8N1, _rx, _tx); + ModuleSerial->begin(baudrate, SERIAL_8N1, _rx, _tx); #else - ModuleSerial->begin(baudrate); + ModuleSerial->begin(baudrate); #endif + } break; case RADIOLIB_USE_I2C: break; diff --git a/src/Module.h b/src/Module.h index cb688435..ddc43c51 100644 --- a/src/Module.h +++ b/src/Module.h @@ -27,14 +27,38 @@ class Module { \param serial HardwareSerial to be used on platforms that do not support SoftwareSerial. Defaults to Serial1. - \param rst Arduino pin to be used as hardware reset for the module. Defaults to -1 (unused). + \param rst Arduino pin to be used as hardware reset for the module. Defaults to NC (unused). */ #ifdef RADIOLIB_SOFTWARE_SERIAL_UNSUPPORTED - Module(int16_t tx, int16_t rx, HardwareSerial* serial = &Serial1, int16_t rst = -1); + Module(int16_t tx, int16_t rx, HardwareSerial* serial = &Serial1, int16_t rst = NC); #else - Module(int16_t tx, int16_t rx, HardwareSerial* serial = nullptr, int16_t rst = -1); + Module(int16_t tx, int16_t rx, HardwareSerial* serial = nullptr, int16_t rst = NC); #endif + /*! + \brief SPI-based module constructor. Will use the default SPI interface automatically initialize it. + + \param cs Arduino pin to be used as chip select. + + \param irq Arduino pin to be used as interrupt/GPIO. + + \param rst Arduino pin to be used as hardware reset for the module. + */ + Module(int16_t cs, int16_t irq, int16_t rst); + + /*! + \brief Extended SPI-based module constructor. Will use the default SPI interface automatically initialize it. + + \param cs Arduino pin to be used as chip select. + + \param irq Arduino pin to be used as interrupt/GPIO. + + \param rst Arduino pin to be used as hardware reset for the module. + + \param gpio Arduino pin to be used as additional interrupt/GPIO. + */ + Module(int16_t cs, int16_t irq, int16_t rst, int16_t gpio); + /*! \brief SPI-based module constructor. @@ -44,11 +68,11 @@ class Module { \param rst Arduino pin to be used as hardware reset for the module. - \param spi SPI interface to be used. Defaults to Arduino hardware SPI interface, can also use software SPI implementations. + \param spi SPI interface to be used, can also use software SPI implementations. - \param spiSettings SPI interface settings. Defaults to 2 MHz clock, MSB first, mode 0. + \param spiSettings SPI interface settings. */ - Module(int16_t cs, int16_t irq, int16_t rst, SPIClass& spi = SPI, SPISettings spiSettings = SPISettings(2000000, MSBFIRST, SPI_MODE0)); + Module(int16_t cs, int16_t irq, int16_t rst, SPIClass& spi, SPISettings spiSettings); /*! \brief Extended SPI-based module constructor. @@ -61,11 +85,11 @@ class Module { \param gpio Arduino pin to be used as additional interrupt/GPIO. - \param spi SPI interface to be used. Defaults to Arduino hardware SPI interface, can also use software SPI implementations. + \param spi SPI interface to be used, can also use software SPI implementations. - \param spiSettings SPI interface settings. Defaults to 2 MHz clock, MSB first, mode 0. + \param spiSettings SPI interface settings. */ - Module(int16_t cs, int16_t irq, int16_t rst, int16_t gpio, SPIClass& spi = SPI, SPISettings spiSettings = SPISettings(2000000, MSBFIRST, SPI_MODE0)); + Module(int16_t cs, int16_t irq, int16_t rst, int16_t gpio, SPIClass& spi, SPISettings spiSettings); /*! \brief Generic module constructor. @@ -344,6 +368,7 @@ class Module { int16_t _irq; int16_t _rst; + bool _initInterface; SPIClass* _spi; SPISettings _spiSettings; diff --git a/src/TypeDef.h b/src/TypeDef.h index fb5455ae..d149ca1b 100644 --- a/src/TypeDef.h +++ b/src/TypeDef.h @@ -9,7 +9,7 @@ // version definitions #define RADIOLIB_VERSION_MAJOR (0x03) -#define RADIOLIB_VERSION_MINOR (0x03) +#define RADIOLIB_VERSION_MINOR (0x04) #define RADIOLIB_VERSION_PATCH (0x00) #define RADIOLIB_VERSION_EXTRA (0x00) diff --git a/src/modules/SX126x/SX126x.cpp b/src/modules/SX126x/SX126x.cpp index b089f247..6b9aa0e4 100644 --- a/src/modules/SX126x/SX126x.cpp +++ b/src/modules/SX126x/SX126x.cpp @@ -131,7 +131,7 @@ int16_t SX126x::beginFSK(float br, float freqDev, float rxBw, float currentLimit state = setSyncWord(sync, 2); RADIOLIB_ASSERT(state); - state = setWhitening(true, 0x0100); + state = setWhitening(true, 0x01FF); RADIOLIB_ASSERT(state); state = variablePacketLengthMode(SX126X_MAX_PACKET_LENGTH); diff --git a/src/modules/SX126x/SX126x.h b/src/modules/SX126x/SX126x.h index df6e8028..1b9ce54f 100644 --- a/src/modules/SX126x/SX126x.h +++ b/src/modules/SX126x/SX126x.h @@ -725,7 +725,7 @@ class SX126x: public PhysicalLayer { \param enabled True = Whitening enabled - \param initial Initial value used for the whitening LFSR in FSK mode. + \param initial Initial value used for the whitening LFSR in FSK mode. Defaults to 0x0100, use 0x01FF for SX127x compatibility. \returns \ref status_codes */ diff --git a/src/modules/SX127x/SX1272.cpp b/src/modules/SX127x/SX1272.cpp index d5bb554c..1251d90a 100644 --- a/src/modules/SX127x/SX1272.cpp +++ b/src/modules/SX127x/SX1272.cpp @@ -57,6 +57,14 @@ int16_t SX1272::beginFSK(float freq, float br, float rxBw, float freqDev, int8_t return(state); } +void SX1272::reset() { + Module::pinMode(_mod->getRst(), OUTPUT); + Module::digitalWrite(_mod->getRst(), HIGH); + delayMicroseconds(100); + Module::digitalWrite(_mod->getRst(), LOW); + delay(5); +} + int16_t SX1272::setFrequency(float freq) { // check frequency range if((freq < 860.0) || (freq > 1020.0)) { @@ -405,6 +413,10 @@ int16_t SX1272::configFSK() { // set fast PLL hop state = _mod->SPIsetRegValue(SX1272_REG_PLL_HOP, SX127X_FAST_HOP_ON, 7, 7); + RADIOLIB_ASSERT(state); + + // set Gauss filter BT product to 0.5 + state = _mod->SPIsetRegValue(SX127X_REG_OP_MODE, SX1272_FSK_GAUSSIAN_0_5, 4, 3); return(state); } diff --git a/src/modules/SX127x/SX1272.h b/src/modules/SX127x/SX1272.h index dd90b739..a0f64541 100644 --- a/src/modules/SX127x/SX1272.h +++ b/src/modules/SX127x/SX1272.h @@ -155,6 +155,11 @@ class SX1272: public SX127x { \returns \ref status_codes */ int16_t beginFSK(float freq = 915.0, float br = 48.0, float rxBw = 125.0, float freqDev = 50.0, int8_t power = 13, uint8_t currentLimit = 100, uint16_t preambleLength = 16, bool enableOOK = false); + + /*! + \brief Reset method. Will reset the chip to the default state using RST pin. + */ + void reset(); // configuration methods diff --git a/src/modules/SX127x/SX1278.cpp b/src/modules/SX127x/SX1278.cpp index b2ab0b3c..24ea9e64 100644 --- a/src/modules/SX127x/SX1278.cpp +++ b/src/modules/SX127x/SX1278.cpp @@ -52,6 +52,14 @@ int16_t SX1278::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t return(state); } +void SX1278::reset() { + Module::pinMode(_mod->getRst(), OUTPUT); + Module::digitalWrite(_mod->getRst(), LOW); + delayMicroseconds(100); + Module::digitalWrite(_mod->getRst(), HIGH); + delay(5); +} + int16_t SX1278::setFrequency(float freq) { // check frequency range if((freq < 137.0) || (freq > 525.0)) { @@ -483,6 +491,10 @@ int16_t SX1278::configFSK() { // set fast PLL hop state = _mod->SPIsetRegValue(SX1278_REG_PLL_HOP, SX127X_FAST_HOP_ON, 7, 7); + RADIOLIB_ASSERT(state); + + // set Gauss filter BT product to 0.5 + state = _mod->SPIsetRegValue(SX127X_REG_PA_RAMP, SX1278_FSK_GAUSSIAN_0_5, 6, 5); return(state); } diff --git a/src/modules/SX127x/SX1278.h b/src/modules/SX127x/SX1278.h index c081e76c..77318e15 100644 --- a/src/modules/SX127x/SX1278.h +++ b/src/modules/SX127x/SX1278.h @@ -165,6 +165,11 @@ class SX1278: public SX127x { */ int16_t beginFSK(float freq = 434.0, float br = 48.0, float freqDev = 50.0, float rxBw = 125.0, int8_t power = 13, uint8_t currentLimit = 100, uint16_t preambleLength = 16, bool enableOOK = false); + /*! + \brief Reset method. Will reset the chip to the default state using RST pin. + */ + void reset(); + // configuration methods /*! diff --git a/src/modules/SX127x/SX127x.cpp b/src/modules/SX127x/SX127x.cpp index 36e4f857..1ba7b49e 100644 --- a/src/modules/SX127x/SX127x.cpp +++ b/src/modules/SX127x/SX127x.cpp @@ -54,9 +54,6 @@ int16_t SX127x::beginFSK(uint8_t chipVersion, float br, float freqDev, float rxB _mod->init(RADIOLIB_USE_SPI); Module::pinMode(_mod->getIrq(), INPUT); - // reset the module - reset(); - // try to find the SX127x chip if(!SX127x::findChip(chipVersion)) { RADIOLIB_DEBUG_PRINTLN(F("No SX127x found!")); @@ -74,6 +71,10 @@ int16_t SX127x::beginFSK(uint8_t chipVersion, float br, float freqDev, float rxB RADIOLIB_ASSERT(state); } + // enable/disable OOK + state = setOOK(enableOOK); + RADIOLIB_ASSERT(state); + // set bit rate state = SX127x::setBitRate(br); RADIOLIB_ASSERT(state); @@ -103,10 +104,6 @@ int16_t SX127x::beginFSK(uint8_t chipVersion, float br, float freqDev, float rxB state = disableAddressFiltering(); RADIOLIB_ASSERT(state); - // enable/disable OOK - state = setOOK(enableOOK); - RADIOLIB_ASSERT(state); - // set default RSSI measurement config state = setRSSIConfig(2); RADIOLIB_ASSERT(state); @@ -121,14 +118,6 @@ int16_t SX127x::beginFSK(uint8_t chipVersion, float br, float freqDev, float rxB return(state); } -void SX127x::reset() { - Module::pinMode(_mod->getRst(), OUTPUT); - Module::digitalWrite(_mod->getRst(), LOW); - delayMicroseconds(100); - Module::digitalWrite(_mod->getRst(), HIGH); - delay(5); -} - int16_t SX127x::transmit(uint8_t* data, size_t len, uint8_t addr) { // set mode to standby int16_t state = setMode(SX127X_STANDBY); diff --git a/src/modules/SX127x/SX127x.h b/src/modules/SX127x/SX127x.h index d48e9e30..aa6bb03b 100644 --- a/src/modules/SX127x/SX127x.h +++ b/src/modules/SX127x/SX127x.h @@ -565,9 +565,9 @@ class SX127x: public PhysicalLayer { int16_t begin(uint8_t chipVersion, uint8_t syncWord, uint8_t currentLimit, uint16_t preambleLength); /*! - \brief Reset method. Will reset the chip to the default state using RST pin. + \brief Reset method. Will reset the chip to the default state using RST pin. Declared pure virtual since SX1272 and SX1278 implmentations differ. */ - void reset(); + virtual void reset() = 0; /*! \brief Initialization method for FSK modem. Will be called with appropriate parameters when calling FSK initialization method from derived class. diff --git a/src/modules/nRF24/nRF24.cpp b/src/modules/nRF24/nRF24.cpp index 3a91862d..732fc20b 100644 --- a/src/modules/nRF24/nRF24.cpp +++ b/src/modules/nRF24/nRF24.cpp @@ -230,14 +230,9 @@ int16_t nRF24::setFrequency(int16_t freq) { return(ERR_INVALID_FREQUENCY); } - // set mode to standby - int16_t state = standby(); - RADIOLIB_ASSERT(state); - // set frequency uint8_t freqRaw = freq - 2400; - state = _mod->SPIsetRegValue(NRF24_REG_RF_CH, freqRaw, 6, 0); - return(state); + return _mod->SPIsetRegValue(NRF24_REG_RF_CH, freqRaw, 6, 0); } int16_t nRF24::setDataRate(int16_t dataRate) { @@ -332,6 +327,7 @@ int16_t nRF24::setTransmitPipe(uint8_t* addr) { // set Rx pipe 0 address (for ACK) _mod->SPIwriteRegisterBurst(NRF24_REG_RX_ADDR_P0, addr, _addrWidth); + state |= _mod->SPIsetRegValue(NRF24_REG_EN_RXADDR, NRF24_P0_ON, 0, 0); return(state); } @@ -423,6 +419,10 @@ int16_t nRF24::getStatus(uint8_t mask) { return(_mod->SPIgetRegValue(NRF24_REG_STATUS) & mask); } +bool nRF24::isCarrierDetected() { + return(_mod->SPIgetRegValue(NRF24_REG_RPD, 0,0)) == 1; +} + int16_t nRF24::setFrequencyDeviation(float freqDev) { // nRF24 is unable to set frequency deviation // this method is implemented only for PhysicalLayer compatibility @@ -438,6 +438,13 @@ size_t nRF24::getPacketLength(bool update) { } int16_t nRF24::setCrcFiltering(bool crcOn) { + // Auto Ack needs to be disabled in order to disable CRC. + if (!crcOn) { + int16_t status = setAutoAck(false); + RADIOLIB_ASSERT(status) + } + + // Disable CRC return _mod->SPIsetRegValue(NRF24_REG_CONFIG, crcOn ? NRF24_CRC_ON : NRF24_CRC_OFF, 3, 3); } diff --git a/src/modules/nRF24/nRF24.h b/src/modules/nRF24/nRF24.h index 6eafc342..70362dfe 100644 --- a/src/modules/nRF24/nRF24.h +++ b/src/modules/nRF24/nRF24.h @@ -127,7 +127,7 @@ // NRF24_REG_STATUS #define NRF24_RX_DR 0b01000000 // 6 6 Rx data ready #define NRF24_TX_DS 0b00100000 // 5 5 Tx data sent -#define NRF24_MAX_RT 0b00010000 // 4 4 maximum number of rentransmits reached (must be cleared to continue) +#define NRF24_MAX_RT 0b00010000 // 4 4 maximum number of retransmits reached (must be cleared to continue) #define NRF24_RX_FIFO_EMPTY 0b00001110 // 3 1 Rx FIFO is empty #define NRF24_RX_P_NO 0b00000000 // 3 1 number of data pipe that received data #define NRF24_TX_FIFO_FULL 0b00000001 // 0 0 Tx FIFO is full @@ -392,6 +392,13 @@ class nRF24: public PhysicalLayer { */ int16_t getStatus(uint8_t mask = 0xFF); + /*! + \brief Checks if carrier was detected during last RX + + \returns Whatever the carrier was above threshold. + */ + bool isCarrierDetected(); + /*! \brief Dummy configuration method, to ensure PhysicalLayer compatibility. @@ -438,7 +445,7 @@ class nRF24: public PhysicalLayer { \returns \ref status_codes */ - int16_t setAutoAck(uint8_t pipeNum, bool autoAckOn = true); + int16_t setAutoAck(uint8_t pipeNum, bool autoAckOn); /*! \brief Dummy data shaping configuration method, to ensure PhysicalLayer compatibility.