From fa9da6b967c872bc2ed3a03a41f869aa07cf2894 Mon Sep 17 00:00:00 2001
From: jgromes <jgromes@users.noreply.github.com>
Date: Sun, 16 Jun 2019 14:33:46 +0200
Subject: [PATCH] [CC1101] Implemented getPacketLength

---
 .../CC1101_Transmit/CC1101_Transmit.ino       |  6 ++--
 src/modules/CC1101.cpp                        | 28 +++++++++++++------
 src/modules/CC1101.h                          | 13 +++++++++
 3 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/examples/CC1101/CC1101_Transmit/CC1101_Transmit.ino b/examples/CC1101/CC1101_Transmit/CC1101_Transmit.ino
index f9272993..87bde6e1 100644
--- a/examples/CC1101/CC1101_Transmit/CC1101_Transmit.ino
+++ b/examples/CC1101/CC1101_Transmit/CC1101_Transmit.ino
@@ -58,11 +58,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 255 bytes
-    Serial.println(F(" too long!"));
+    // the supplied packet was longer than 64 bytes
+    Serial.println(F("too long!"));
 
   } else {
     // some other error occurred
diff --git a/src/modules/CC1101.cpp b/src/modules/CC1101.cpp
index 3e87c7c0..3bf6d4f9 100644
--- a/src/modules/CC1101.cpp
+++ b/src/modules/CC1101.cpp
@@ -1,7 +1,8 @@
 #include "CC1101.h"
 
-CC1101::CC1101(Module* module) : PhysicalLayer(CC1101_CRYSTAL_FREQ, CC1101_DIV_EXPONENT) {
+CC1101::CC1101(Module* module) : PhysicalLayer(CC1101_CRYSTAL_FREQ, CC1101_DIV_EXPONENT, CC1101_MAX_PACKET_LENGTH) {
   _mod = module;
+  _packetLengthQueried = false;
 }
 
 int16_t CC1101::begin(float freq, float br, float rxBw, float freqDev, int8_t power) {
@@ -175,7 +176,7 @@ void CC1101::setGdo2Action(void (*func)(void), uint8_t dir) {
 
 int16_t CC1101::startTransmit(uint8_t* data, size_t len, uint8_t addr) {
   // check packet length
-  if(len > 63) {
+  if(len > CC1101_MAX_PACKET_LENGTH) {
     return(ERR_PACKET_TOO_LONG);
   }
 
@@ -230,7 +231,10 @@ int16_t CC1101::startReceive() {
 
 int16_t CC1101::readData(uint8_t* data, size_t len) {
   // get packet length
-  size_t length = SPIreadRegister(CC1101_REG_RXBYTES) - 2;
+  size_t length = len;
+  if(len == CC1101_MAX_PACKET_LENGTH) {
+    length = getPacketLength();
+  }
 
   // check address filtering
   uint8_t filter = SPIgetRegValue(CC1101_REG_PKTCTRL1, 1, 0);
@@ -239,12 +243,6 @@ int16_t CC1101::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];
-  }
   SPIreadRegisterBurst(CC1101_REG_FIFO, length, data);
 
   // read RSSI byte
@@ -260,6 +258,9 @@ int16_t CC1101::readData(uint8_t* data, size_t len) {
   // flush Rx FIFO
   SPIsendCommand(CC1101_CMD_FLUSH_RX);
 
+  // clear internal flag so getPacketLength can return the new packet length
+  _packetLengthQueried = false;
+
   // set mode to standby
   standby();
 
@@ -474,6 +475,15 @@ uint8_t CC1101::getLQI() {
   return(_rawLQI);
 }
 
+size_t CC1101::getPacketLength(bool update) {
+  if(!_packetLengthQueried && update) {
+    _packetLength = _mod->SPIreadRegister(CC1101_REG_FIFO);
+    _packetLengthQueried = true;
+  }
+
+  return(_packetLength);
+}
+
 int16_t CC1101::config() {
   // enable automatic frequency synthesizer calibration
   int16_t state = SPIsetRegValue(CC1101_REG_MCSM0, CC1101_FS_AUTOCAL_IDLE_TO_RXTX, 5, 4);
diff --git a/src/modules/CC1101.h b/src/modules/CC1101.h
index f512fdf8..a2060819 100644
--- a/src/modules/CC1101.h
+++ b/src/modules/CC1101.h
@@ -9,6 +9,7 @@
 // CC1101 physical layer properties
 #define CC1101_CRYSTAL_FREQ                           26.0
 #define CC1101_DIV_EXPONENT                           16
+#define CC1101_MAX_PACKET_LENGTH                      63
 
 // CC1101 SPI commands
 #define CC1101_CMD_READ                               0b10000000
@@ -729,6 +730,15 @@ class CC1101: public PhysicalLayer {
     */
     uint8_t getLQI();
 
+     /*!
+      \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);
+
   private:
     Module* _mod;
 
@@ -736,6 +746,9 @@ class CC1101: public PhysicalLayer {
     uint8_t _rawRSSI;
     uint8_t _rawLQI;
 
+    size_t _packetLength;
+    bool _packetLengthQueried;
+
     int16_t config();
     int16_t directMode();
     void getExpMant(float target, uint16_t mantOffset, uint8_t divExp, uint8_t expMax, uint8_t& exp, uint8_t& mant);