From 3ad5dfa44462bc08f0f2558341c2d38688d4507f Mon Sep 17 00:00:00 2001 From: jgromes Date: Sun, 16 Jun 2019 14:33:59 +0200 Subject: [PATCH] [RF69] Implemented getPacketLength --- examples/RF69/RF69_Transmit/RF69_Transmit.ino | 4 +- src/modules/RF69.cpp | 64 +++++++++++-------- src/modules/RF69.h | 17 ++++- 3 files changed, 57 insertions(+), 28 deletions(-) diff --git a/examples/RF69/RF69_Transmit/RF69_Transmit.ino b/examples/RF69/RF69_Transmit/RF69_Transmit.ino index dca4f975..eb818b22 100644 --- a/examples/RF69/RF69_Transmit/RF69_Transmit.ino +++ b/examples/RF69/RF69_Transmit/RF69_Transmit.ino @@ -59,11 +59,11 @@ void loop() { if (state == ERR_NONE) { // the packet was successfully transmitted - Serial.println(F(" success!")); + Serial.println(F("success!")); } else if (state == ERR_PACKET_TOO_LONG) { // the supplied packet was longer than 64 bytes - Serial.println(F(" too long!")); + Serial.println(F("too long!")); } else { // some other error occurred diff --git a/src/modules/RF69.cpp b/src/modules/RF69.cpp index 91918416..951e6aba 100644 --- a/src/modules/RF69.cpp +++ b/src/modules/RF69.cpp @@ -1,8 +1,9 @@ #include "RF69.h" -RF69::RF69(Module* module) : PhysicalLayer(RF69_CRYSTAL_FREQ, RF69_DIV_EXPONENT) { +RF69::RF69(Module* module) : PhysicalLayer(RF69_CRYSTAL_FREQ, RF69_DIV_EXPONENT, RF69_MAX_PACKET_LENGTH) { _mod = module; _tempOffset = 0; + _packetLengthQueried = false; } int16_t RF69::begin(float freq, float br, float rxBw, float freqDev, int8_t power) { @@ -102,7 +103,7 @@ int16_t RF69::transmit(uint8_t* data, size_t len, uint8_t addr) { int16_t RF69::receive(uint8_t* data, size_t len) { // start reception - int16_t state = startReceive(); + int16_t state = startReceive(true); if(state != ERR_NONE) { return(state); } @@ -191,27 +192,31 @@ int16_t RF69::disableAES() { return(_mod->SPIsetRegValue(RF69_REG_PACKET_CONFIG_2, RF69_AES_OFF, 0, 0)); } -int16_t RF69::startReceive() { +int16_t RF69::startReceive(bool timeout) { // set mode to standby int16_t state = setMode(RF69_STANDBY); - // set DIO pin mapping - state |= _mod->SPIsetRegValue(RF69_REG_DIO_MAPPING_1, RF69_DIO0_PACK_PAYLOAD_READY, 7, 6); - - // clear interrupt flags - clearIRQFlags(); - - // disable RX timeouts - state |= _mod->SPIsetRegValue(RF69_REG_RX_TIMEOUT_1, RF69_TIMEOUT_RX_START_OFF); - state |= _mod->SPIsetRegValue(RF69_REG_RX_TIMEOUT_2, RF69_TIMEOUT_RSSI_THRESH_OFF); + // set RX timeouts and DIO pin mapping + if(timeout) { + state = _mod->SPIsetRegValue(RF69_REG_DIO_MAPPING_1, RF69_DIO0_PACK_PAYLOAD_READY | RF69_DIO1_PACK_TIMEOUT, 7, 4); + state |= _mod->SPIsetRegValue(RF69_REG_RX_TIMEOUT_1, RF69_TIMEOUT_RX_START); + state |= _mod->SPIsetRegValue(RF69_REG_RX_TIMEOUT_2, RF69_TIMEOUT_RSSI_THRESH); + } else { + state = _mod->SPIsetRegValue(RF69_REG_DIO_MAPPING_1, RF69_DIO0_PACK_PAYLOAD_READY, 7, 6); + state |= _mod->SPIsetRegValue(RF69_REG_RX_TIMEOUT_1, RF69_TIMEOUT_RX_START_OFF); + state |= _mod->SPIsetRegValue(RF69_REG_RX_TIMEOUT_2, RF69_TIMEOUT_RSSI_THRESH_OFF); + } if(state != ERR_NONE) { return(state); } + // clear interrupt flags + clearIRQFlags(); + // set mode to receive - state = setMode(RF69_RX); - state |= _mod->SPIsetRegValue(RF69_REG_TEST_PA1, RF69_PA1_NORMAL); + state = _mod->SPIsetRegValue(RF69_REG_TEST_PA1, RF69_PA1_NORMAL); state |= _mod->SPIsetRegValue(RF69_REG_TEST_PA2, RF69_PA2_NORMAL); + state |= setMode(RF69_RX); return(state); } @@ -226,7 +231,7 @@ void RF69::setDio1Action(void (*func)(void)) { int16_t RF69::startTransmit(uint8_t* data, size_t len, uint8_t addr) { // check packet length - if(len > 64) { + if(len > RF69_MAX_PACKET_LENGTH) { return(ERR_PACKET_TOO_LONG); } @@ -264,7 +269,10 @@ int16_t RF69::startTransmit(uint8_t* data, size_t len, uint8_t addr) { int16_t RF69::readData(uint8_t* data, size_t len) { // get packet length - size_t length = _mod->SPIreadRegister(RF69_REG_FIFO); + size_t length = len; + if(len == RF69_MAX_PACKET_LENGTH) { + length = getPacketLength(); + } // check address filtering uint8_t filter = _mod->SPIgetRegValue(RF69_REG_PACKET_CONFIG_1, 2, 1); @@ -273,12 +281,6 @@ int16_t RF69::readData(uint8_t* data, size_t len) { } // read packet data - if(len == 0) { - // argument len equal to zero indicates String call, which means dynamically allocated data array - // dispose of the original and create a new one - delete[] data; - data = new uint8_t[length + 1]; - } _mod->SPIreadRegisterBurst(RF69_REG_FIFO, length, data); // add terminating null @@ -287,6 +289,9 @@ int16_t RF69::readData(uint8_t* data, size_t len) { // update RSSI lastPacketRSSI = -1.0 * (_mod->SPIgetRegValue(RF69_REG_RSSI_VALUE)/2.0); + // clear internal flag so getPacketLength can return the new packet length + _packetLengthQueried = false; + // clear interrupt flags clearIRQFlags(); @@ -443,9 +448,9 @@ int16_t RF69::setFrequencyDeviation(float freqDev) { // set frequency deviation from carrier frequency uint32_t base = 1; - uint32_t FDEV = (freqDev * (base << 19)) / 32000; - int16_t state = _mod->SPIsetRegValue(RF69_REG_FDEV_MSB, (FDEV & 0xFF00) >> 8, 5, 0); - state |= _mod->SPIsetRegValue(RF69_REG_FDEV_LSB, FDEV & 0x00FF, 7, 0); + uint32_t fdev = (freqDev * (base << 19)) / 32000; + int16_t state = _mod->SPIsetRegValue(RF69_REG_FDEV_MSB, (fdev & 0xFF00) >> 8, 5, 0); + state |= _mod->SPIsetRegValue(RF69_REG_FDEV_LSB, fdev & 0x00FF, 7, 0); return(state); } @@ -556,6 +561,15 @@ int16_t RF69::getTemperature() { return(0 - (rawTemp + _tempOffset)); } +size_t RF69::getPacketLength(bool update) { + if(!_packetLengthQueried && update) { + _packetLength = _mod->SPIreadRegister(RF69_REG_FIFO); + _packetLengthQueried = true; + } + + return(_packetLength); +} + int16_t RF69::config() { int16_t state = ERR_NONE; diff --git a/src/modules/RF69.h b/src/modules/RF69.h index 26a959a2..15fe18dc 100644 --- a/src/modules/RF69.h +++ b/src/modules/RF69.h @@ -9,6 +9,7 @@ // RF69 physical layer properties #define RF69_CRYSTAL_FREQ 32.0 #define RF69_DIV_EXPONENT 19 +#define RF69_MAX_PACKET_LENGTH 64 // RF69 register map #define RF69_REG_FIFO 0x00 @@ -580,9 +581,11 @@ class RF69: public PhysicalLayer { /*! \brief Interrupt-driven receive method. GDO0 will be activated when full packet is received. + \param timeout Enable module-driven timeout. Set to false for listen mode. + \returns \ref status_codes */ - int16_t startReceive(); + int16_t startReceive(bool timeout = false); /*! \brief Reads data received after calling startReceive method. @@ -694,6 +697,15 @@ class RF69: public PhysicalLayer { */ int16_t getTemperature(); + /*! + \brief Query modem for the packet length of received payload. + + \param update Update received packet length. Will return cached value when set to false. + + \returns Length of last received packet in bytes. + */ + size_t getPacketLength(bool update = true); + protected: Module* _mod; @@ -701,6 +713,9 @@ class RF69: public PhysicalLayer { float _rxBw; int16_t _tempOffset; + size_t _packetLength; + bool _packetLengthQueried; + int16_t config(); int16_t directMode();