Start cleanup

This commit is contained in:
Nanosonde 2020-11-03 23:02:28 +01:00
parent 197ea94ab8
commit 0ae9b6d3fb
8 changed files with 168 additions and 511 deletions

View File

@ -166,8 +166,6 @@ set(${PROJECT_NAME}_SOURCES
./RTT/SEGGER_RTT.c ./RTT/SEGGER_RTT.c
./RTT/SEGGER_RTT.h ./RTT/SEGGER_RTT.h
./RTT/SEGGER_RTT_ASM_ARMv7M.S ./RTT/SEGGER_RTT_ASM_ARMv7M.S
./RFQueue.c
./RFQueue.h
./smartrf_settings/smartrf_settings.c ./smartrf_settings/smartrf_settings.c
./smartrf_settings/smartrf_settings.h ./smartrf_settings/smartrf_settings.h
./CC1310_LAUNCHXL_fxns.c ./CC1310_LAUNCHXL_fxns.c

View File

@ -1,133 +0,0 @@
/******************************************************************************
* Filename: rf_queue.c
* Revised: $ $
* Revision: $ $
*
* Description: Help functions for handling queues
*
* Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Standard C Libraries */
#include <stdint.h>
#include <stdlib.h>
/* Application Header files */
#include "RFQueue.h"
#include <ti/devices/DeviceFamily.h>
#include DeviceFamily_constructPath(driverlib/rf_data_entry.h)
/* Receive entry pointer to keep track of read items */
rfc_dataEntryGeneral_t* readEntry;
//*****************************************************************************
//
//! Get the current dataEntry
//!
//! \return rfc_dataEntry*
//
//*****************************************************************************
rfc_dataEntryGeneral_t*
RFQueue_getDataEntry()
{
return (readEntry);
}
//*****************************************************************************
//
//! Move to next dataEntry
//!
//! \return None
//
//*****************************************************************************
uint8_t
RFQueue_nextEntry()
{
/* Set status to pending */
readEntry->status = DATA_ENTRY_PENDING;
/* Move read entry pointer to next entry */
readEntry = (rfc_dataEntryGeneral_t*)readEntry->pNextEntry;
return (readEntry->status);
}
//*****************************************************************************
//
//! Define a queue
//!
//! \param dataQueue is a pointer to the queue to use
//! \param buf is the prealocated byte buffer to use
//! \param buf_len is the number of preallocated bytes
//! \param numEntries are the number of dataEntries to split the buffer into
//! \param length is the length of data in every dataEntry
//!
//! \return uint8_t
//
//*****************************************************************************
uint8_t
RFQueue_defineQueue(dataQueue_t *dataQueue, uint8_t *buf, uint16_t buf_len, uint8_t numEntries, uint16_t length)
{
if (buf_len < (numEntries * (length + RF_QUEUE_DATA_ENTRY_HEADER_SIZE + RF_QUEUE_QUEUE_ALIGN_PADDING(length))))
{
/* queue does not fit into buffer */
return (1);
}
/* Padding needed for 4-byte alignment? */
uint8_t pad = 4-((length + RF_QUEUE_DATA_ENTRY_HEADER_SIZE)%4);
/* Set the Data Entries common configuration */
uint8_t *first_entry = buf;
int i;
for (i = 0; i < numEntries; i++)
{
buf = first_entry + i * (RF_QUEUE_DATA_ENTRY_HEADER_SIZE + length + pad);
((rfc_dataEntry_t*)buf)->status = DATA_ENTRY_PENDING; // Pending - starting state
((rfc_dataEntry_t*)buf)->config.type = DATA_ENTRY_TYPE_GEN; // General Data Entry
((rfc_dataEntry_t*)buf)->config.lenSz = 0; // No length indicator byte in data
((rfc_dataEntry_t*)buf)->length = length; // Total length of data field
((rfc_dataEntryGeneral_t*)buf)->pNextEntry = &(((rfc_dataEntryGeneral_t*)buf)->data)+length+pad;
}
/* Make circular Last.Next -> First */
((rfc_dataEntry_t*)buf)->pNextEntry = first_entry;
/* Create Data Entry Queue and configure for circular buffer Data Entries */
dataQueue->pCurrEntry = first_entry;
dataQueue->pLastEntry = NULL;
/* Set read pointer to first entry */
readEntry = (rfc_dataEntryGeneral_t*)first_entry;
return (0);
}

View File

@ -1,79 +0,0 @@
/******************************************************************************
* Filename: rf_queue.h
* Revised: $ $
* Revision: $ $
*
* Description: Help functions for handling queues
*
* Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
//*****************************************************************************
//
//! \addtogroup rfqueue_api
//! @{
//
//*****************************************************************************
#ifndef RF_QUEUE_H
#define RF_QUEUE_H
#include <ti/devices/DeviceFamily.h>
#include DeviceFamily_constructPath(driverlib/rf_data_entry.h)
#define RF_QUEUE_DATA_ENTRY_HEADER_SIZE 8 // Contant header size of a Generic Data Entry
#define RF_QUEUE_QUEUE_ALIGN_PADDING(length) (4-((length + RF_QUEUE_DATA_ENTRY_HEADER_SIZE)%4)) // Padding offset
#define RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(numEntries, dataSize, appendedBytes) \
(numEntries*(RF_QUEUE_DATA_ENTRY_HEADER_SIZE + dataSize + appendedBytes + RF_QUEUE_QUEUE_ALIGN_PADDING(dataSize + appendedBytes)))
#ifdef __cplusplus
extern "C" {
#endif
extern uint8_t RFQueue_nextEntry();
extern rfc_dataEntryGeneral_t* RFQueue_getDataEntry();
extern uint8_t RFQueue_defineQueue(dataQueue_t *queue ,uint8_t *buf, uint16_t buf_len, uint8_t numEntries, uint16_t length);
#ifdef __cplusplus
}
#endif
#endif
//*****************************************************************************
//
//! Close the Doxygen group.
//! @}
//
//*****************************************************************************

View File

@ -5,23 +5,20 @@
// //
//********************************************************************************* //*********************************************************************************
//********************************************************************************* //*********************************************************************************
// Parameter summary // Parameter summary
// Address: off // Address: on
// Address0: 0xAA // Address0: 0x44FF
// Address1: 0xBB
// Frequency: 868.29999 MHz // Frequency: 868.29999 MHz
// Data Format: Serial mode disable // Data Format: Serial mode disable
// Deviation: 50.000 kHz // Deviation: 50.000 kHz
// Packet Length Config: Variable // Max Packet Length: unlimited packet length mode
// Max Packet Length: 128
// Packet Length: 20
// RX Filter BW: 196 kHz // RX Filter BW: 196 kHz
// Symbol Rate: 32.76825 kBaud // Symbol Rate: 32.76825 kBaud
// Sync Word Length: 24 Bits // Sync Word Length: 24 Bits
// TX Power: 14 dBm (requires define CCFG_FORCE_VDDR_HH = 1 in ccfg.c, see CC13xx/CC26xx Technical Reference Manual) // TX Power: 14 dBm (requires define CCFG_FORCE_VDDR_HH = 1 in ccfg.c, see CC13xx/CC26xx Technical Reference Manual)
// Whitening: No whitening // Whitening: No whitening
// FEC mode: manchester code
#include <ti/devices/DeviceFamily.h> #include <ti/devices/DeviceFamily.h>
#include DeviceFamily_constructPath(driverlib/rf_mailbox.h) #include DeviceFamily_constructPath(driverlib/rf_mailbox.h)
@ -182,47 +179,6 @@ rfc_CMD_PROP_TX_t RF_cmdPropTx =
.pPkt = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx .pPkt = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
}; };
// CMD_PROP_RX
rfc_CMD_PROP_RX_t RF_cmdPropRx =
{
.commandNo = 0x3802,
.status = 0x0000,
.pNextOp = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
.startTime = 0x00000000,
.startTrigger.triggerType = 0x0,
.startTrigger.bEnaCmd = 0x0,
.startTrigger.triggerNo = 0x0,
.startTrigger.pastTrig = 0x0,
.condition.rule = 0x1,
.condition.nSkip = 0x0,
.pktConf.bFsOff = 0x0,
.pktConf.bRepeatOk = 0x0,
.pktConf.bRepeatNok = 0x0,
.pktConf.bUseCrc = 0x1,
.pktConf.bVarLen = 0x1,
.pktConf.bChkAddress = 0x0,
.pktConf.endType = 0x0,
.pktConf.filterOp = 0x0,
.rxConf.bAutoFlushIgnored = 0x0,
.rxConf.bAutoFlushCrcErr = 0x0,
.rxConf.bIncludeHdr = 0x1,
.rxConf.bIncludeCrc = 0x0,
.rxConf.bAppendRssi = 0x0,
.rxConf.bAppendTimestamp = 0x0,
.rxConf.bAppendStatus = 0x1,
.syncWord = 0x547696,
.maxPktLen = 0x80, // MAKE SURE DATA ENTRY IS LARGE ENOUGH
.address0 = 0xAA,
.address1 = 0xBB,
.endTrigger.triggerType = 0x1,
.endTrigger.bEnaCmd = 0x0,
.endTrigger.triggerNo = 0x0,
.endTrigger.pastTrig = 0x0,
.endTime = 0x00000000,
.pQueue = 0, // INSERT APPLICABLE POINTER: (dataQueue_t*)&xxx
.pOutput = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
};
// CMD_PROP_RX_ADV // CMD_PROP_RX_ADV
rfc_CMD_PROP_RX_ADV_t RF_cmdPropRxAdv = rfc_CMD_PROP_RX_ADV_t RF_cmdPropRxAdv =
{ {
@ -239,11 +195,11 @@ rfc_CMD_PROP_RX_ADV_t RF_cmdPropRxAdv =
.pktConf.bFsOff = 0x0, .pktConf.bFsOff = 0x0,
.pktConf.bRepeatOk = 0x0, .pktConf.bRepeatOk = 0x0,
.pktConf.bRepeatNok = 0x0, .pktConf.bRepeatNok = 0x0,
.pktConf.bUseCrc = 0x0, .pktConf.bUseCrc = 0x0, // CRC engine cannot be used
.pktConf.bCrcIncSw = 0x0, .pktConf.bCrcIncSw = 0x0,
.pktConf.bCrcIncHdr = 0x1, .pktConf.bCrcIncHdr = 0x1,
.pktConf.endType = 0x0, .pktConf.endType = 0x0,
.pktConf.filterOp = 0x1, .pktConf.filterOp = 0x0,
.rxConf.bAutoFlushIgnored = 0x0, .rxConf.bAutoFlushIgnored = 0x0,
.rxConf.bAutoFlushCrcErr = 0x0, .rxConf.bAutoFlushCrcErr = 0x0,
.rxConf.bIncludeHdr = 0x1, .rxConf.bIncludeHdr = 0x1,
@ -251,16 +207,16 @@ rfc_CMD_PROP_RX_ADV_t RF_cmdPropRxAdv =
.rxConf.bAppendRssi = 0x0, .rxConf.bAppendRssi = 0x0,
.rxConf.bAppendTimestamp = 0x0, .rxConf.bAppendTimestamp = 0x0,
.rxConf.bAppendStatus = 0x0, .rxConf.bAppendStatus = 0x0,
.syncWord0 = 0x547696, .syncWord0 = 0x547696, // KNX-RF syncword
.syncWord1 = 0, .syncWord1 = 0,
.maxPktLen = 0, .maxPktLen = 0,
.hdrConf.numHdrBits = 8, .hdrConf.numHdrBits = 8, // One length byte in header
.hdrConf.lenPos = 0, .hdrConf.lenPos = 0,
.hdrConf.numLenBits = 8, .hdrConf.numLenBits = 8, // Header length is just the length byte
.addrConf.addrType = 0, .addrConf.addrType = 0, // Address bytes AFTER header
.addrConf.addrSize = 0, .addrConf.addrSize = 2, // use the two fixed bytes (0x44 and 0xff) after the length byte as address bytes
.addrConf.addrPos = 0, .addrConf.addrPos = 0,
.addrConf.numAddr = 1, .addrConf.numAddr = 1, // just the two fixed bytes are used as one address
.lenOffset = 0, .lenOffset = 0,
.endTrigger.triggerType = 0x1, .endTrigger.triggerType = 0x1,
.endTrigger.bEnaCmd = 0x0, .endTrigger.bEnaCmd = 0x0,
@ -272,29 +228,30 @@ rfc_CMD_PROP_RX_ADV_t RF_cmdPropRxAdv =
.pOutput = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx .pOutput = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
}; };
// CMD_TX_TEST // TX Power table
rfc_CMD_TX_TEST_t RF_cmdTxTest = // The RF_TxPowerTable_DEFAULT_PA_ENTRY macro is defined in RF.h and requires the following arguments:
{ // RF_TxPowerTable_DEFAULT_PA_ENTRY(bias, gain, boost coefficient)
.commandNo = 0x0808, // See the Technical Reference Manual for further details about the "txPower" Command field.
.status = 0x0000, // The PA settings require the CCFG_FORCE_VDDR_HH = 0 unless stated otherwise.
.pNextOp = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx const RF_TxPowerTable_Entry PROP_RF_txPowerTable[] =
.startTime = 0x00000000, {
.startTrigger.triggerType = 0x0, {-10, RF_TxPowerTable_DEFAULT_PA_ENTRY(0, 3, 0, 4) },
.startTrigger.bEnaCmd = 0x0, {0, RF_TxPowerTable_DEFAULT_PA_ENTRY(1, 1, 0, 0) },
.startTrigger.triggerNo = 0x0, {1, RF_TxPowerTable_DEFAULT_PA_ENTRY(3, 3, 0, 8) },
.startTrigger.pastTrig = 0x0, {2, RF_TxPowerTable_DEFAULT_PA_ENTRY(2, 1, 0, 8) },
.condition.rule = 0x1, {3, RF_TxPowerTable_DEFAULT_PA_ENTRY(4, 3, 0, 10) },
.condition.nSkip = 0x0, {4, RF_TxPowerTable_DEFAULT_PA_ENTRY(5, 3, 0, 12) },
.config.bUseCw = 0x0, {5, RF_TxPowerTable_DEFAULT_PA_ENTRY(6, 3, 0, 12) },
.config.bFsOff = 0x1, {6, RF_TxPowerTable_DEFAULT_PA_ENTRY(7, 3, 0, 14) },
.config.whitenMode = 0x2, {7, RF_TxPowerTable_DEFAULT_PA_ENTRY(9, 3, 0, 16) },
.__dummy0 = 0x00, {8, RF_TxPowerTable_DEFAULT_PA_ENTRY(11, 3, 0, 18) },
.txWord = 0xABCD, {9, RF_TxPowerTable_DEFAULT_PA_ENTRY(13, 3, 0, 22) },
.__dummy1 = 0x00, {10, RF_TxPowerTable_DEFAULT_PA_ENTRY(19, 3, 0, 28) },
.endTrigger.triggerType = 0x1, {11, RF_TxPowerTable_DEFAULT_PA_ENTRY(26, 3, 0, 40) },
.endTrigger.bEnaCmd = 0x0, {12, RF_TxPowerTable_DEFAULT_PA_ENTRY(24, 0, 0, 92) },
.endTrigger.triggerNo = 0x0, {13, RF_TxPowerTable_DEFAULT_PA_ENTRY(63, 0, 0, 83) }, // The original PA value (12.5 dBm) have been rounded to an integer value.
.endTrigger.pastTrig = 0x0, {14, RF_TxPowerTable_DEFAULT_PA_ENTRY(63, 0, 1, 83) }, // This setting requires CCFG_FORCE_VDDR_HH = 1.
.syncWord = 0x930B51DE, RF_TxPowerTable_TERMINATION_ENTRY
.endTime = 0x00000000,
}; };
const uint8_t PROP_RF_txPowerTableSize = sizeof(PROP_RF_txPowerTable)/sizeof(RF_TxPowerTable_Entry);

View File

@ -14,6 +14,10 @@
#include DeviceFamily_constructPath(driverlib/rf_prop_cmd.h) #include DeviceFamily_constructPath(driverlib/rf_prop_cmd.h)
#include <ti/drivers/rf/RF.h> #include <ti/drivers/rf/RF.h>
// RF Core TX power
extern const RF_TxPowerTable_Entry PROP_RF_txPowerTable[];
extern const uint8_t PROP_RF_txPowerTableSize;
// TI-RTOS RF Mode Object // TI-RTOS RF Mode Object
extern RF_Mode RF_prop; extern RF_Mode RF_prop;
@ -21,8 +25,6 @@ extern RF_Mode RF_prop;
extern rfc_CMD_PROP_RADIO_DIV_SETUP_t RF_cmdPropRadioDivSetup; extern rfc_CMD_PROP_RADIO_DIV_SETUP_t RF_cmdPropRadioDivSetup;
extern rfc_CMD_FS_t RF_cmdFs; extern rfc_CMD_FS_t RF_cmdFs;
extern rfc_CMD_PROP_TX_t RF_cmdPropTx; extern rfc_CMD_PROP_TX_t RF_cmdPropTx;
extern rfc_CMD_PROP_RX_t RF_cmdPropRx; extern rfc_CMD_PROP_RX_ADV_t RF_cmdPropRxAdv;
extern rfc_CMD_PROP_RX_ADV_t RF_pCmdPropRxAdv;
extern rfc_CMD_TX_TEST_t RF_cmdTxTest;
#endif // _SMARTRF_SETTINGS_H_ #endif // _SMARTRF_SETTINGS_H_

View File

@ -404,28 +404,6 @@ void RfPhysicalLayer::showRegisterSettings()
printHex("", Patable_verify, 8); printHex("", Patable_verify, 8);
} }
uint16_t RfPhysicalLayer::packetSize (uint8_t lField)
{
uint16_t nrBytes;
uint8_t nrBlocks;
// The 2 first blocks contains 25 bytes when excluding CRC and the L-field
// The other blocks contains 16 bytes when excluding the CRC-fields
// Less than 26 (15 + 10)
if ( lField < 26 )
nrBlocks = 2;
else
nrBlocks = (((lField - 26) / 16) + 3);
// Add all extra fields, excluding the CRC fields
nrBytes = lField + 1;
// Add the CRC fields, each block has 2 CRC bytes
nrBytes += (2 * nrBlocks);
return nrBytes;
}
void RfPhysicalLayer::loop() void RfPhysicalLayer::loop()
{ {
switch (_loopState) switch (_loopState)
@ -452,7 +430,7 @@ void RfPhysicalLayer::loop()
_rfDataLinkLayer.loadNextTxFrame(&sendBuffer, &sendBufferLength); _rfDataLinkLayer.loadNextTxFrame(&sendBuffer, &sendBufferLength);
// Calculate total number of bytes in the KNX RF packet from L-field // Calculate total number of bytes in the KNX RF packet from L-field
pktLen = packetSize(sendBuffer[0]); pktLen = PACKET_SIZE(sendBuffer[0]);
// Check for valid length // Check for valid length
if ((pktLen == 0) || (pktLen > 290)) if ((pktLen == 0) || (pktLen > 290))
{ {
@ -658,7 +636,7 @@ void RfPhysicalLayer::loop()
break; break;
} }
// Get bytes to receive from L-field, multiply by 2 because of manchester code // Get bytes to receive from L-field, multiply by 2 because of manchester code
pktLen = 2 * packetSize(packet[0]); pktLen = 2 * PACKET_SIZE(packet[0]);
// - Length mode - // - Length mode -
if (pktLen < 256) if (pktLen < 256)
@ -751,7 +729,7 @@ void RfPhysicalLayer::loop()
case RX_END: case RX_END:
{ {
uint16_t pLen = packetSize(packet[0]); uint16_t pLen = PACKET_SIZE(packet[0]);
// Decode the first block (always 10 bytes + 2 bytes CRC) // Decode the first block (always 10 bytes + 2 bytes CRC)
bool decodeOk = true; bool decodeOk = true;
for (uint16_t i = 1; i < pLen; i++) for (uint16_t i = 1; i < pLen; i++)

View File

@ -182,6 +182,9 @@ extern void delayMicroseconds (unsigned int howLong);
#define TX_ACTIVE 4 #define TX_ACTIVE 4
#define TX_END 5 #define TX_END 5
// Calculate the real packet size out of the L-field of FT3 frame data. See KNX-RF spec. 3.2.5 Data Link Layer frame format
#define PACKET_SIZE(lField) ((((lField - 10 /*size of first pkt*/))/16 + 2 /*CRC in first pkt */) * 2 /*to bytes*/ +lField + 1 /*size of len byte*/)
class RfDataLinkLayer; class RfDataLinkLayer;
class RfPhysicalLayer class RfPhysicalLayer
@ -209,8 +212,6 @@ class RfPhysicalLayer
void powerDownCC1101(); void powerDownCC1101();
void setOutputPowerLevel(int8_t dBm); void setOutputPowerLevel(int8_t dBm);
uint16_t packetSize (uint8_t lField);
uint8_t sIdle(); uint8_t sIdle();
uint8_t sReceive(); uint8_t sReceive();

View File

@ -1,21 +1,3 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Copyright(c) 2020 - Matthias Meier */
#include "config.h" #include "config.h"
#ifdef USE_RF #ifdef USE_RF
@ -26,9 +8,10 @@
#include "rf_physical_layer.h" #include "rf_physical_layer.h"
#include "rf_data_link_layer.h" #include "rf_data_link_layer.h"
#include "smartrf_settings/smartrf_settings.h" #include <ti/devices/DeviceFamily.h>
#include DeviceFamily_constructPath(driverlib/rf_data_entry.h)
#include <ti/drivers/rf/RF.h> #include <ti/drivers/rf/RF.h>
#include "RFQueue.h" #include "smartrf_settings/smartrf_settings.h"
#include "cc1310_platform.h" #include "cc1310_platform.h"
#include "Board.h" #include "Board.h"
@ -36,47 +19,41 @@
#include "bits.h" #include "bits.h"
#include "platform.h" #include "platform.h"
#define RX_MAX_BUFFER_LENGTH 256
#define RF_TERMINATION_EVENT_MASK (RF_EventLastCmdDone | RF_EventLastFGCmdDone | RF_EventCmdAborted | RF_EventCmdStopped | RF_EventCmdCancelled)
static RF_Object rfObject; static RF_Object rfObject;
RF_Handle rfHandle; static RF_Handle rfHandle;
RF_CmdHandle rxCommandHandle; static RF_CmdHandle rxCommandHandle;
uint8_t lastRssi;
#define DATA_ENTRY_HEADER_SIZE 12 /* Constant header size of a Generic Data Entry - 12 for DATA_ENTRY_TYPE_PARTIAL, 8 for DATA_ENTRY_TYPE_GEN */
#define MAX_LENGTH 255
#define LENGTH_POSITION 0
#define APPENDED_BYTES 10
static uint8_t rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE + MAX_LENGTH + LENGTH_POSITION + APPENDED_BYTES] __attribute__((aligned(4)));
rfc_dataEntryPartial_t* partialReadEntry = (rfc_dataEntryPartial_t*)&rxDataEntryBuffer;
static uint8_t rxBuffer[sizeof(rfc_dataEntryPartial_t) + RX_MAX_BUFFER_LENGTH] __attribute__((aligned(4)));
static rfc_dataEntryPartial_t* pDataEntry = (rfc_dataEntryPartial_t*)&rxBuffer;
static dataQueue_t dataQueue; static dataQueue_t dataQueue;
static rfc_dataEntryGeneral_t* currentDataEntry;
static uint8_t addrFilterTable[2] = {0x44, 0xFF}; // Do not modify the size without changing RF_cmdPropRxAdv.addrConf.addrSize!
static rfc_propRxOutput_t rxStatistics;
static uint8_t packetLength; static uint8_t packetLength;
static uint8_t* packetDataPointer; static uint8_t* packetDataPointer;
static int32_t packetStartTime;
volatile static int frags; static volatile int rf_done, rf_err, err;
volatile static int rf_done, rf_err, err;
int8_t len1, len2; int8_t len1, len2;
rfc_propRxOutput_t rxStatistics; static void RxCallback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
static volatile uint8_t lengthWritten = false;
static volatile uint8_t rxDone = false;
int32_t packetStartTime;
#define PACKET_SIZE(lField) ((((lField - 10 /*size of first pkt*/))/16 + 2 /*CRC in first pkt */) * 2 /*to bytes*/ +lField + 1 /*size of len byte*/)
void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
{ {
frags++; if (e & RF_EventNDataWritten)
if (e & RF_EventNDataWritten && frags==1)
{ {
//uint16_t block1Crc = rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE + 10] << 8 | rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE + 11]; uint8_t *pData = &pDataEntry->rxData;
if ((rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE + 1] != 0x44) || (rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE + 2] != 0xFF) /*|| (crc16(&rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE], 0, 10) != block1Crc)*/) { if ((pData[1] != 0x44) || (pData[2] != 0xFF))
// cancel because not a KNX package ID {
// cancel early because it does not seem to be KNX RF packet
RF_cancelCmd(rfHandle, rxCommandHandle, 0 /*stop gracefully*/); RF_cancelCmd(rfHandle, rxCommandHandle, 0 /*stop gracefully*/);
return; return;
} }
uint8_t len = rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE + 0]; //uint8_t len = rxBuffer[sizeof(rfc_dataEntryPartial_t) + 0];
uint8_t len = pDataEntry->rxData;
struct rfc_CMD_PROP_SET_LEN_s RF_cmdPropSetLen = struct rfc_CMD_PROP_SET_LEN_s RF_cmdPropSetLen =
{ {
.commandNo = CMD_PROP_SET_LEN, // command identifier .commandNo = CMD_PROP_SET_LEN, // command identifier
@ -84,18 +61,19 @@ void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
}; };
len1=len; len2 = RF_cmdPropSetLen.rxLen; len1=len; len2 = RF_cmdPropSetLen.rxLen;
//RF_cmdPropSetLen.rxLen = 40; //RF_runImmediateCmd(rfHandle, (uint32_t*)&RF_cmdPropSetLen); // for length > 255
RF_runDirectCmd(rfHandle, (uint32_t)&RF_cmdPropSetLen); RF_runDirectCmd(rfHandle, (uint32_t)&RF_cmdPropSetLen);
packetStartTime = millis(); packetStartTime = millis();
} }
else if (e & (RF_EventLastCmdDone | RF_EventCmdStopped | RF_EventCmdAborted | RF_EventCmdCancelled)) { else if (e & RF_TERMINATION_EVENT_MASK)
{
rf_done = true; rf_done = true;
rf_err = e & (RF_EventCmdStopped | RF_EventCmdAborted | RF_EventCmdCancelled); rf_err = e & (RF_EventCmdStopped | RF_EventCmdAborted | RF_EventCmdCancelled);
} }
else /* unknown reason - should not occure */ else /* unknown reason - should not occure */
{ {
partialReadEntry->status = DATA_ENTRY_PENDING; pDataEntry->status = DATA_ENTRY_PENDING;
err++; err++;
} }
} }
@ -109,36 +87,43 @@ RfPhysicalLayer::RfPhysicalLayer(RfDataLinkLayer& rfDataLinkLayer, Platform& pla
void RfPhysicalLayer::setOutputPowerLevel(int8_t dBm) void RfPhysicalLayer::setOutputPowerLevel(int8_t dBm)
{ {
/* RF_TxPowerTable_Entry *rfPowerTable = NULL;
* TODO: Complete if needed RF_TxPowerTable_Value newValue;
* Refs: uint8_t rfPowerTableSize = 0;
* https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz/f/156/t/540423?How-to-dynamically-change-tx-power-from-10dBm-to-14dBm-when-running-CC1310-application-
* https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz/f/156/t/561302?Increase-TX-power-of-cc1310-stepwise // Search the default PA power table for the desired power level
* Power Table from Conticki: newValue = RF_TxPowerTable_findValue((RF_TxPowerTable_Entry *)PROP_RF_txPowerTable, dBm);
const prop_mode_tx_power_config_t prop_mode_tx_power_779_930[] = { if(newValue.rawValue != RF_TxPowerTable_INVALID_VALUE)
{ 14, 0xa73f }, // needs CCFG_FORCE_VDDR_HH=1 {
{ 13, 0xa63f }, // 12.5dB // Found a valid entry
{ 12, 0xb818 }, rfPowerTable = (RF_TxPowerTable_Entry *)PROP_RF_txPowerTable;
{ 11, 0x50da }, rfPowerTableSize = PROP_RF_txPowerTableSize;
{ 10, 0x38d3 }, }
{ 9, 0x2ccd },
{ 8, 0x24cb }, //if max power is requested then the CCFG_FORCE_VDDR_HH must be set in
{ 7, 0x20c9 }, //the ccfg
{ 6, 0x1cc7 }, #if (CCFG_FORCE_VDDR_HH != 0x1)
{ 5, 0x18c6 }, if((newValue.paType == RF_TxPowerTable_DefaultPA) &&
{ 4, 0x18c5 }, (dBm == rfPowerTable[rfPowerTableSize-2].power))
{ 3, 0x14c4 }, {
{ 2, 0x1042 }, // The desired power level is set to the maximum supported under the
{ 1, 0x10c3 }, // default PA settings, but the boost mode (CCFG_FORCE_VDDR_HH) is not
{ 0, 0x0041 }, // turned on
{ -10, 0x08c0 }, return;
{-128, 0xFFFF }, }
}; #endif
* code to change power to eg. 14dBm :
* RF_yield(rfHandle); RF_Stat rfStatus = RF_setTxPower(rfHandle, newValue);
* RF_cmdPropRadioDivSetup.txPower = 0xA73F; if(rfStatus == RF_StatSuccess)
* RF_EventMask result = RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal, NULL, 0); {
*/ print("Successfully set TX output power to: ");
println(newValue.rawValue);
}
else
{
print("Could not set TX output power to: ");
println(newValue.rawValue);
}
} }
@ -147,35 +132,25 @@ bool RfPhysicalLayer::InitChip()
RF_Params rfParams; RF_Params rfParams;
RF_Params_init(&rfParams); RF_Params_init(&rfParams);
if( RFQueue_defineQueue(&dataQueue, pDataEntry->length = 255;
rxDataEntryBuffer, pDataEntry->config.type = DATA_ENTRY_TYPE_PARTIAL; // --> DATA_ENTRY_TYPE_PARTIAL adds a 12 Byte Header
sizeof(rxDataEntryBuffer), pDataEntry-> config.irqIntv = 12; // KNX-RF first block consists of 12 bytes (one length byte, 0x44, 0xFF, one RFinfo byte, six Serial/DoA bytes, two CRC bytes)
1, pDataEntry-> config.lenSz = 0; // no length indicator at beginning of data entry
MAX_LENGTH + APPENDED_BYTES)) pDataEntry->status = DATA_ENTRY_PENDING;
{ pDataEntry->pNextEntry = (uint8_t*)pDataEntry;
println("Failed to allocate space for all data entries");
while(1);
}
partialReadEntry->length = 255; dataQueue.pCurrEntry = (uint8_t*)pDataEntry;
partialReadEntry->config.type = DATA_ENTRY_TYPE_PARTIAL; // --> DATA_ENTRY_TYPE_PARTIAL adds a 12 Byte Header
partialReadEntry-> config.irqIntv = 12;
partialReadEntry-> config.lenSz = 0; // len field not handeld by rf core because it does not include CRC bytes
partialReadEntry->status = DATA_ENTRY_PENDING;
partialReadEntry->pNextEntry = (uint8_t*)partialReadEntry;
dataQueue.pCurrEntry = (uint8_t*)partialReadEntry;
dataQueue.pLastEntry = NULL; dataQueue.pLastEntry = NULL;
/* 4.1. Modify CMD_PROP_RX command for application needs */ // Set buffer with address. We use the two fixed bytes 0x44 and 0xFF as our address to let the
RF_cmdPropRx.pQueue = &dataQueue; /* Set the Data Entity queue for received data */ // packet engine do more filtering on itself
RF_cmdPropRx.maxPktLen = 0; /* Unlimited length */ RF_cmdPropRxAdv.pAddr = (uint8_t*)&addrFilterTable;
RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 0x0; /* Auto-flush packets with invalid CRC */ // Set the Data Entity queue for received data
RF_cmdPropRx.pktConf.bRepeatNok = 0x0; /* Exit RX after a packet is recived */ RF_cmdPropRxAdv.pQueue = &dataQueue;
RF_cmdPropRx.pktConf.bRepeatOk = 0x0; /* Exit RX after a packet is recived */ // Set the output buffer for RX packet statistics
RF_cmdPropRx.pOutput = (uint8_t*)&rxStatistics; RF_cmdPropRxAdv.pOutput = (uint8_t*)&rxStatistics;
/* Request access to the radio */ // Request access to the radio
rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams); rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);
/* Set the frequency */ /* Set the frequency */
@ -185,37 +160,14 @@ bool RfPhysicalLayer::InitChip()
void RfPhysicalLayer::stopChip() void RfPhysicalLayer::stopChip()
{ {
RF_cancelCmd(rfHandle, rxCommandHandle, 0 /*stop RF abort */); RF_cancelCmd(rfHandle, rxCommandHandle, 0 /* do not stop gracefully, instead hard abort RF */);
RF_pendCmd(rfHandle, rxCommandHandle, 0); RF_pendCmd(rfHandle, rxCommandHandle, RF_TERMINATION_EVENT_MASK);
RF_yield(rfHandle); RF_yield(rfHandle);
} RF_close(rfHandle);
uint16_t RfPhysicalLayer::packetSize (uint8_t lField)
{
uint16_t nrBytes;
uint8_t nrBlocks;
// The 2 first blocks contains 25 bytes when excluding CRC and the L-field
// The other blocks contains 16 bytes when excluding the CRC-fields
// Less than 26 (15 + 10)
if ( lField < 26 )
nrBlocks = 2;
else
nrBlocks = (((lField - 26) / 16) + 3);
// Add all extra fields, excluding the CRC fields
nrBytes = lField + 1;
// Add the CRC fields, each block has 2 CRC bytes
nrBytes += (2 * nrBlocks);
return nrBytes;
} }
void RfPhysicalLayer::loop() void RfPhysicalLayer::loop()
{ {
static uint8_t lastRxOk;
switch (_loopState) switch (_loopState)
{ {
case TX_START: case TX_START:
@ -223,10 +175,9 @@ void RfPhysicalLayer::loop()
println("TX_START..."); println("TX_START...");
_rfDataLinkLayer.loadNextTxFrame(&sendBuffer, &sendBufferLength); _rfDataLinkLayer.loadNextTxFrame(&sendBuffer, &sendBufferLength);
pktLen = PACKET_SIZE(sendBuffer[0]); pktLen = PACKET_SIZE(sendBuffer[0]);
//pktLen = packetSize(sendBuffer[0]); if (pktLen != sendBufferLength)
if (PACKET_SIZE(sendBuffer[0]) != packetSize(sendBuffer[0]) || PACKET_SIZE(sendBuffer[0]) != sendBufferLength)
{ {
printf("Error: SendBuffer[0]=%d, SendBufferLength=%d PACKET_SIZE=%d, packetSize=%d\n", sendBuffer[0], sendBufferLength, PACKET_SIZE(sendBuffer[0]), packetSize(sendBuffer[0])); printf("Error: SendBuffer[0]=%d, SendBufferLength=%d PACKET_SIZE=%d\n", sendBuffer[0], sendBufferLength, PACKET_SIZE(sendBuffer[0]));
} }
// Calculate total number of bytes in the KNX RF packet from L-field // Calculate total number of bytes in the KNX RF packet from L-field
// Check for valid length // Check for valid length
@ -245,7 +196,7 @@ void RfPhysicalLayer::loop()
RF_cmdPropTx.pktLen = pktLen; RF_cmdPropTx.pktLen = pktLen;
RF_cmdPropTx.pPkt = sendBuffer; RF_cmdPropTx.pPkt = sendBuffer;
RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW; RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;
RF_EventMask res = RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal, NULL, 0); RF_EventMask res = RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal, NULL, RF_TERMINATION_EVENT_MASK);
delete sendBuffer; delete sendBuffer;
@ -260,14 +211,10 @@ void RfPhysicalLayer::loop()
case RX_START: case RX_START:
{ {
//print("RX_START...\n");
frags = 0;
rf_done = rf_err = false; rf_done = rf_err = false;
err = 0; err = 0;
lastRxOk = rxStatistics.nRxOk;
//RF_EventMask res = RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, &callback, IRQ_RX_N_DATA_WRITTEN);
rxCommandHandle = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, &callback, IRQ_RX_N_DATA_WRITTEN); rxCommandHandle = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRxAdv, RF_PriorityNormal, &RxCallback, IRQ_RX_N_DATA_WRITTEN);
if (rxCommandHandle == RF_ALLOC_ERROR) if (rxCommandHandle == RF_ALLOC_ERROR)
{ {
println("Error: nRF_pendCmd() failed"); println("Error: nRF_pendCmd() failed");
@ -281,9 +228,9 @@ void RfPhysicalLayer::loop()
{ {
if (!_rfDataLinkLayer.isTxQueueEmpty() && !syncStart) if (!_rfDataLinkLayer.isTxQueueEmpty() && !syncStart)
{ {
RF_cancelCmd(rfHandle, rxCommandHandle, 1 /*stop gracefully*/); RF_cancelCmd(rfHandle, rxCommandHandle, RF_ABORT_GRACEFULLY);
RF_pendCmd(rfHandle, rxCommandHandle, 0); RF_pendCmd(rfHandle, rxCommandHandle, RF_TERMINATION_EVENT_MASK);
RFQueue_nextEntry(); pDataEntry->status = DATA_ENTRY_PENDING;
_loopState = TX_START; _loopState = TX_START;
break; break;
} }
@ -292,67 +239,53 @@ void RfPhysicalLayer::loop()
if (!rf_done && syncStart && (millis() - packetStartTime > RX_PACKET_TIMEOUT)) if (!rf_done && syncStart && (millis() - packetStartTime > RX_PACKET_TIMEOUT))
{ {
println("RX packet timeout!"); println("RX packet timeout!");
RF_cancelCmd(rfHandle, rxCommandHandle, 1 /*stop gracefully*/); RF_cancelCmd(rfHandle, rxCommandHandle, RF_ABORT_GRACEFULLY);
RF_pendCmd(rfHandle, rxCommandHandle, 0); RF_pendCmd(rfHandle, rxCommandHandle, RF_TERMINATION_EVENT_MASK);
RFQueue_nextEntry(); pDataEntry->status = DATA_ENTRY_PENDING;
_loopState = RX_START; _loopState = RX_START;
break; break;
} }
else if (rf_done) else if (rf_done)
{ {
RF_EventMask res = RF_pendCmd(rfHandle, rxCommandHandle, 0); RF_EventMask res = RF_pendCmd(rfHandle, rxCommandHandle, RF_TERMINATION_EVENT_MASK);
/*
if (rxStatistics.nRxOk == lastRxOk)
{
println("Rx empty or invalid");
}
else if ( rxStatistics.lastRssi < -120)
{
println("\nIgnoring Rx with rssi < -120dB");
}
*/
if (res == RF_EventCmdCancelled || res == RF_EventCmdStopped || res == RF_EventCmdAborted) if (res == RF_EventCmdCancelled || res == RF_EventCmdStopped || res == RF_EventCmdAborted)
{ {
println("RF terminated because of RF_flushCmd() or RF_cancelCmd()"); println("RF terminated because of RF_flushCmd() or RF_cancelCmd()");
} }
else if (res != RF_EventLastCmdDone) else if (res != RF_EventLastCmdDone)
{ {
printf("Unexpected Rx result command %llu\n", res); //printf("Unexpected Rx result command %llu\n", res);
print("Unexpected Rx result command: ");
println(res, HEX);
} }
else if (rf_err) else if (rf_err)
{ {
print("Rx is no KNX frame\n\n"); println("Rx is no KNX frame");
} }
else else
{ {
printf("len1=%d, len1=%d, frags=%d, err=%d\n", len1, len2, frags, err); //printf("len1=%d, len1=%d, frags=%d, err=%d\n", len1, len2, frags, err);
printf("nRxOk = %d ", rxStatistics.nRxOk); //!< Number of packets that have been received with payload, CRC OK and not ignored print("nRxOk = ");println(rxStatistics.nRxOk); //!< Number of packets that have been received with payload, CRC OK and not ignored
printf("nRxNok = %d ", rxStatistics.nRxNok); //!< Number of packets that have been received with CRC error print("nRxNok = ");println(rxStatistics.nRxNok); //!< Number of packets that have been received with CRC error
printf("nRxIgnored = %d ", rxStatistics.nRxIgnored); //!< Number of packets that have been received with CRC OK and ignored due to address mismatch print("nRxIgnored = ");println(rxStatistics.nRxIgnored); //!< Number of packets that have been received with CRC OK and ignored due to address mismatch
printf("nRxStopped = %d ", rxStatistics.nRxStopped); //!< Number of packets not received due to illegal length or address mismatch with pktConf.filterOp = 1 print("nRxStopped = ");println(rxStatistics.nRxStopped); //!< Number of packets not received due to illegal length or address mismatch with pktConf.filterOp = 1
printf("nRxBufFull = %d ", rxStatistics.nRxBufFull); //!< Number of packets that have been received and discarded due to lack of buffer space print("nRxBufFull = ");println(rxStatistics.nRxBufFull); //!< Number of packets that have been received and discarded due to lack of buffer space
printf("lastRssi = %d\n", rxStatistics.lastRssi); //!< RSSI of last received packet print("lastRssi = ");println(rxStatistics.lastRssi); //!< RSSI of last received packet
currentDataEntry = RFQueue_getDataEntry(); // add CRC sizes for received blocks, but do not add the length of the L-field (1 byte) itself
/* Handle the packet data, located at &currentDataEntry->data: packetLength = PACKET_SIZE(pDataEntry->rxData);
* For unknown reason, there is a header of 4 bytes whereas nr bytes rececived +1 is at offset [2]*/ packetDataPointer = (uint8_t *) &pDataEntry->rxData;
packetLength = *(uint8_t *)(&(currentDataEntry->data)+4);
if (PACKET_SIZE(packetLength) != PACKET_SIZE(packetLength)) if (packetLength+1 != pDataEntry->nextIndex)
printf("Error RX: packetLength=%d PACKET_SIZE=%d, packetSize=%d\n", packetLength, PACKET_SIZE(packetLength), packetSize(packetLength)); {
//printf("Size mismatch: %d %d\n", packetLength, *(uint8_t *)(&(currentDataEntry->data)+2));
//printf("Size mismatch: %d %d\n", packetLength, pDataEntry->nextIndex);
println("Size mismatch");
}
packetLength = PACKET_SIZE(packetLength); // add CRC size printHex("RX: ", packetDataPointer, packetLength);
packetDataPointer = (uint8_t *)(&(currentDataEntry->data)+4); _rfDataLinkLayer.frameBytesReceived(packetDataPointer, packetLength);
pDataEntry->status = DATA_ENTRY_PENDING;
if (packetLength+1 != *(uint8_t *)(&(currentDataEntry->data)+2)) {
printf("Size mismatch: %d %d\n", packetLength, *(uint8_t *)(&(currentDataEntry->data)+2));
printf("Data Start: 0x%x 0x%x 0x%x\n", packetDataPointer[0], packetDataPointer[1], packetDataPointer[2]);
}
lastRssi = rxStatistics.lastRssi; // TODO: save rssi only if frame was addressed to this node
printHex("RX: ", packetDataPointer, packetLength);
_rfDataLinkLayer.frameBytesReceived(packetDataPointer, packetLength);
RFQueue_nextEntry();
} }
_loopState = RX_START; _loopState = RX_START;
} }