continue cleanup

This commit is contained in:
Nanosonde 2020-11-04 16:08:58 +01:00
parent 0ae9b6d3fb
commit 8768725246
9 changed files with 408 additions and 312 deletions

View File

@ -138,6 +138,7 @@ set(${PROJECT_NAME}_SOURCES
../../src/knx/rf_medium_object.cpp
../../src/knx/rf_medium_object.h
../../src/knx/rf_physical_layer_cc1310.cpp
../../src/knx/rf_physical_layer_cc1310.h
../../src/knx/rf_physical_layer.h
../../src/knx/router_object.cpp
../../src/knx/router_object.h

View File

@ -5,7 +5,11 @@
#include "bau_systemB_device.h"
#include "rf_medium_object.h"
#include "rf_physical_layer.h"
#if defined(DeviceFamily_CC13X0)
#include "rf_physical_layer_cc1310.h"
#else
#include "rf_physical_layer_cc1101.h"
#endif
#include "rf_data_link_layer.h"
#include "cemi_server.h"
#include "cemi_server_object.h"

View File

@ -1,7 +1,11 @@
#include "config.h"
#ifdef USE_RF
#include "rf_physical_layer.h"
#if defined(DeviceFamily_CC13X0)
#include "rf_physical_layer_cc1310.h"
#else
#include "rf_physical_layer_cc1101.h"
#endif
#include "rf_data_link_layer.h"
#include "bits.h"

View File

@ -8,13 +8,15 @@
#define MAX_KNX_TELEGRAM_SIZE 263
class RfPhysicalLayer;
class RfMediumObject;
class RfDataLinkLayer : public DataLinkLayer
{
friend class RfPhysicalLayer;
#if defined(DeviceFamily_CC13X0)
friend class RfPhysicalLayerCC1310;
#else
friend class RfPhysicalLayerCC1101;
#endif
using DataLinkLayer::_deviceObject;
using DataLinkLayer::_platform;
@ -49,8 +51,11 @@ class RfDataLinkLayer : public DataLinkLayer
} _tx_queue;
RfMediumObject& _rfMediumObj;
RfPhysicalLayer _rfPhy;
#if defined(DeviceFamily_CC13X0)
RfPhysicalLayerCC1310 _rfPhy;
#else
RfPhysicalLayerCC1101 _rfPhy;
#endif
void fillRfFrame(CemiFrame& frame, uint8_t* data);
void addFrameTxQueue(CemiFrame& frame);
bool isTxQueueEmpty();

View File

@ -7,181 +7,6 @@
#include "platform.h"
/*----------------------------------[standard]--------------------------------*/
#define CC1101_TIMEOUT 2000 // Time to wait for a response from CC1101
#define RX_PACKET_TIMEOUT 20 // Wait 20ms for packet reception to complete
#define TX_PACKET_TIMEOUT 20 // Wait 20ms for packet reception to complete
#ifdef __linux__ // Linux Platform
extern void delayMicroseconds (unsigned int howLong);
#endif
/*----------------------[CC1101 - misc]---------------------------------------*/
#define CRYSTAL_FREQUENCY 26000000
#define CFG_REGISTER 0x2F //47 registers
#define FIFOBUFFER 0x42 //size of Fifo Buffer +2 for rssi and lqi
#define RSSI_OFFSET_868MHZ 0x4E //dec = 74
#define TX_RETRIES_MAX 0x05 //tx_retries_max
#define ACK_TIMEOUT 250 //ACK timeout in ms
#define CC1101_COMPARE_REGISTER 0x00 //register compare 0=no compare 1=compare
#define BROADCAST_ADDRESS 0x00 //broadcast address
#define CC1101_FREQ_315MHZ 0x01
#define CC1101_FREQ_434MHZ 0x02
#define CC1101_FREQ_868MHZ 0x03
#define CC1101_FREQ_915MHZ 0x04
#define CC1101_TEMP_ADC_MV 3.225 //3.3V/1023 . mV pro digit
#define CC1101_TEMP_CELS_CO 2.47 //Temperature coefficient 2.47mV per Grad Celsius
/*---------------------------[CC1101 - R/W offsets]---------------------------*/
#define WRITE_SINGLE_BYTE 0x00
#define WRITE_BURST 0x40
#define READ_SINGLE_BYTE 0x80
#define READ_BURST 0xC0
/*---------------------------[END R/W offsets]--------------------------------*/
/*------------------------[CC1101 - FIFO commands]----------------------------*/
#define TXFIFO_BURST 0x7F //write burst only
#define TXFIFO_SINGLE_BYTE 0x3F //write single only
#define RXFIFO_BURST 0xFF //read burst only
#define RXFIFO_SINGLE_BYTE 0xBF //read single only
#define PATABLE_BURST 0x7E //power control read/write
#define PATABLE_SINGLE_BYTE 0xFE //power control read/write
/*---------------------------[END FIFO commands]------------------------------*/
/*----------------------[CC1101 - config register]----------------------------*/
#define IOCFG2 0x00 // GDO2 output pin configuration
#define IOCFG1 0x01 // GDO1 output pin configuration
#define IOCFG0 0x02 // GDO0 output pin configuration
#define FIFOTHR 0x03 // RX FIFO and TX FIFO thresholds
#define SYNC1 0x04 // Sync word, high byte
#define SYNC0 0x05 // Sync word, low byte
#define PKTLEN 0x06 // Packet length
#define PKTCTRL1 0x07 // Packet automation control
#define PKTCTRL0 0x08 // Packet automation control
#define DEVADDR 0x09 // Device address
#define CHANNR 0x0A // Channel number
#define FSCTRL1 0x0B // Frequency synthesizer control
#define FSCTRL0 0x0C // Frequency synthesizer control
#define FREQ2 0x0D // Frequency control word, high byte
#define FREQ1 0x0E // Frequency control word, middle byte
#define FREQ0 0x0F // Frequency control word, low byte
#define MDMCFG4 0x10 // Modem configuration
#define MDMCFG3 0x11 // Modem configuration
#define MDMCFG2 0x12 // Modem configuration
#define MDMCFG1 0x13 // Modem configuration
#define MDMCFG0 0x14 // Modem configuration
#define DEVIATN 0x15 // Modem deviation setting
#define MCSM2 0x16 // Main Radio Cntrl State Machine config
#define MCSM1 0x17 // Main Radio Cntrl State Machine config
#define MCSM0 0x18 // Main Radio Cntrl State Machine config
#define FOCCFG 0x19 // Frequency Offset Compensation config
#define BSCFG 0x1A // Bit Synchronization configuration
#define AGCCTRL2 0x1B // AGC control
#define AGCCTRL1 0x1C // AGC control
#define AGCCTRL0 0x1D // AGC control
#define WOREVT1 0x1E // High byte Event 0 timeout
#define WOREVT0 0x1F // Low byte Event 0 timeout
#define WORCTRL 0x20 // Wake On Radio control
#define FREND1 0x21 // Front end RX configuration
#define FREND0 0x22 // Front end TX configuration
#define FSCAL3 0x23 // Frequency synthesizer calibration
#define FSCAL2 0x24 // Frequency synthesizer calibration
#define FSCAL1 0x25 // Frequency synthesizer calibration
#define FSCAL0 0x26 // Frequency synthesizer calibration
#define RCCTRL1 0x27 // RC oscillator configuration
#define RCCTRL0 0x28 // RC oscillator configuration
#define FSTEST 0x29 // Frequency synthesizer cal control
#define PTEST 0x2A // Production test
#define AGCTEST 0x2B // AGC test
#define TEST2 0x2C // Various test settings
#define TEST1 0x2D // Various test settings
#define TEST0 0x2E // Various test settings
/*-------------------------[END config register]------------------------------*/
/*------------------------[CC1101-command strobes]----------------------------*/
#define SRES 0x30 // Reset chip
#define SFSTXON 0x31 // Enable/calibrate freq synthesizer
#define SXOFF 0x32 // Turn off crystal oscillator.
#define SCAL 0x33 // Calibrate freq synthesizer & disable
#define SRX 0x34 // Enable RX.
#define STX 0x35 // Enable TX.
#define SIDLE 0x36 // Exit RX / TX
#define SAFC 0x37 // AFC adjustment of freq synthesizer
#define SWOR 0x38 // Start automatic RX polling sequence
#define SPWD 0x39 // Enter pwr down mode when CSn goes hi
#define SFRX 0x3A // Flush the RX FIFO buffer.
#define SFTX 0x3B // Flush the TX FIFO buffer.
#define SWORRST 0x3C // Reset real time clock.
#define SNOP 0x3D // No operation.
/*-------------------------[END command strobes]------------------------------*/
/*----------------------[CC1101 - status register]----------------------------*/
#define PARTNUM 0xF0 // Part number
#define VERSION 0xF1 // Current version number
#define FREQEST 0xF2 // Frequency offset estimate
#define LQI 0xF3 // Demodulator estimate for link quality
#define RSSI 0xF4 // Received signal strength indication
#define MARCSTATE 0xF5 // Control state machine state
#define WORTIME1 0xF6 // High byte of WOR timer
#define WORTIME0 0xF7 // Low byte of WOR timer
#define PKTSTATUS 0xF8 // Current GDOx status and packet status
#define VCO_VC_DAC 0xF9 // Current setting from PLL cal module
#define TXBYTES 0xFA // Underflow and # of bytes in TXFIFO
#define RXBYTES 0xFB // Overflow and # of bytes in RXFIFO
#define RCCTRL1_STATUS 0xFC //Last RC Oscillator Calibration Result
#define RCCTRL0_STATUS 0xFD //Last RC Oscillator Calibration Result
//--------------------------[END status register]-------------------------------
/*----------------------[CC1101 - Main Radio Control State Machine states]-----*/
#define MARCSTATE_BITMASK 0x1F
#define MARCSTATE_SLEEP 0x00
#define MARCSTATE_IDLE 0x01
#define MARCSTATE_XOFF 0x02
#define MARCSTATE_VCOON_MC 0x03
#define MARCSTATE_REGON_MC 0x04
#define MARCSTATE_MANCAL 0x05
#define MARCSTATE_VCOON 0x06
#define MARCSTATE_REGON 0x07
#define MARCSTATE_STARTCAL 0x08
#define MARCSTATE_BWBOOST 0x09
#define MARCSTATE_FS_LOCK 0x0A
#define MARCSTATE_IFADCON 0x0B
#define MARCSTATE_ENDCAL 0x0C
#define MARCSTATE_RX 0x0D
#define MARCSTATE_RX_END 0x0E
#define MARCSTATE_RX_RST 0x0F
#define MARCSTATE_TXRX_SWITCH 0x10
#define MARCSTATE_RXFIFO_OVERFLOW 0x11
#define MARCSTATE_FSTXON 0x12
#define MARCSTATE_TX 0x13
#define MARCSTATE_TX_END 0x14
#define MARCSTATE_RXTX_SWITCH 0x15
#define MARCSTATE_TXFIFO_UNDERFLOW 0x16
// Chip Status Byte
// Bit fields in the chip status byte
#define CHIPSTATUS_CHIP_RDYn_BITMASK 0x80
#define CHIPSTATUS_STATE_BITMASK 0x70
#define CHIPSTATUS_FIFO_BYTES_AVAILABLE_BITMASK 0x0F
// Chip states
#define CHIPSTATUS_STATE_IDLE 0x00
#define CHIPSTATUS_STATE_RX 0x10
#define CHIPSTATUS_STATE_TX 0x20
#define CHIPSTATUS_STATE_FSTXON 0x30
#define CHIPSTATUS_STATE_CALIBRATE 0x40
#define CHIPSTATUS_STATE_SETTLING 0x50
#define CHIPSTATUS_STATE_RX_OVERFLOW 0x60
#define CHIPSTATUS_STATE_TX_UNDERFLOW 0x70
// loop states
#define RX_START 0
#define RX_ACTIVE 1
#define RX_END 2
#define TX_START 3
#define TX_ACTIVE 4
#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*/)
@ -190,55 +15,14 @@ class RfDataLinkLayer;
class RfPhysicalLayer
{
public:
RfPhysicalLayer(RfDataLinkLayer& rfDataLinkLayer, Platform& platform);
RfPhysicalLayer(RfDataLinkLayer& rfDataLinkLayer, Platform& platform)
: _rfDataLinkLayer(rfDataLinkLayer), _platform(platform) {}
bool InitChip();
void showRegisterSettings();
void stopChip();
void loop();
private:
// Table for encoding 4-bit data into a 8-bit Manchester encoding.
static const uint8_t manchEncodeTab[16];
// Table for decoding 4-bit Manchester encoded data into 2-bit
static const uint8_t manchDecodeTab[16];
static const uint8_t cc1101_2FSK_32_7_kb[CFG_REGISTER];
static const uint8_t paTablePower868[8];
void manchEncode(uint8_t *uncodedData, uint8_t *encodedData);
bool manchDecode(uint8_t *encodedData, uint8_t *decodedData);
void powerDownCC1101();
void setOutputPowerLevel(int8_t dBm);
uint8_t sIdle();
uint8_t sReceive();
void spiWriteRegister(uint8_t spi_instr, uint8_t value);
uint8_t spiReadRegister(uint8_t spi_instr);
uint8_t spiWriteStrobe(uint8_t spi_instr);
void spiReadBurst(uint8_t spi_instr, uint8_t *pArr, uint8_t len);
void spiWriteBurst(uint8_t spi_instr, const uint8_t *pArr, uint8_t len);
uint8_t _loopState = RX_START;
bool syncStart = false;
bool packetStart = true;
bool fixedLengthMode = false;
uint8_t *sendBuffer {0};
uint16_t sendBufferLength {0};
uint8_t packet[512];
uint8_t buffer[sizeof(packet)*2]; // We need twice the space due to manchester encoding
uint8_t* pByteIndex = &buffer[0];
uint16_t pktLen {0};
uint16_t bytesLeft = {0};
uint8_t statusGDO0 {0};
uint8_t statusGDO2 {0};
uint8_t prevStatusGDO0 {0}; // for edge detection during polling
uint8_t prevStatusGDO2 {0}; // for edge detection during polling
uint32_t packetStartTime {0};
virtual bool InitChip() = 0;
virtual void stopChip() = 0;
virtual void loop() = 0;
protected:
RfDataLinkLayer& _rfDataLinkLayer;
Platform& _platform;
};

View File

@ -1,7 +1,7 @@
#include "config.h"
#ifdef USE_RF
#include "rf_physical_layer.h"
#include "rf_physical_layer_cc1101.h"
#include "rf_data_link_layer.h"
#include "bits.h"
@ -15,7 +15,7 @@
#define ABS(x) ((x > 0) ? (x) : (-x))
// Table for encoding 4-bit data into a 8-bit Manchester encoding.
const uint8_t RfPhysicalLayer::manchEncodeTab[16] = {0xAA, // 0x0 Manchester encoded
const uint8_t RfPhysicalLayerCC1101::manchEncodeTab[16] = {0xAA, // 0x0 Manchester encoded
0xA9, // 0x1 Manchester encoded
0xA6, // 0x2 Manchester encoded
0xA5, // 0x3 Manchester encoded
@ -34,7 +34,7 @@ const uint8_t RfPhysicalLayer::manchEncodeTab[16] = {0xAA, // 0x0 Manchester
// Table for decoding 4-bit Manchester encoded data into 2-bit
// data. 0xFF indicates invalid Manchester encoding
const uint8_t RfPhysicalLayer::manchDecodeTab[16] = {0xFF, // Manchester encoded 0x0 decoded
const uint8_t RfPhysicalLayerCC1101::manchDecodeTab[16] = {0xFF, // Manchester encoded 0x0 decoded
0xFF, // Manchester encoded 0x1 decoded
0xFF, // Manchester encoded 0x2 decoded
0xFF, // Manchester encoded 0x3 decoded
@ -78,7 +78,7 @@ const uint8_t RfPhysicalLayer::manchDecodeTab[16] = {0xFF, // Manchester encode
// Device address = 0
// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at the end of the packet
// GDO2 signal selection = ( 0) Asserts when RX FiFO threshold
const uint8_t RfPhysicalLayer::cc1101_2FSK_32_7_kb[CFG_REGISTER] = {
const uint8_t RfPhysicalLayerCC1101::cc1101_2FSK_32_7_kb[CFG_REGISTER] = {
0x00, // IOCFG2 GDO2 Output Pin Configuration
0x2E, // IOCFG1 GDO1 Output Pin Configuration
0x06, // IOCFG0 GDO0 Output Pin Configuration
@ -129,15 +129,15 @@ const uint8_t RfPhysicalLayer::cc1101_2FSK_32_7_kb[CFG_REGISTER] = {
};
//Patable index: -30 -20- -15 -10 0 5 7 10 dBm
const uint8_t RfPhysicalLayer::paTablePower868[8] = {0x03,0x17,0x1D,0x26,0x50,0x86,0xCD,0xC0};
const uint8_t RfPhysicalLayerCC1101::paTablePower868[8] = {0x03,0x17,0x1D,0x26,0x50,0x86,0xCD,0xC0};
RfPhysicalLayer::RfPhysicalLayer(RfDataLinkLayer& rfDataLinkLayer, Platform& platform)
RfPhysicalLayerCC1101::RfPhysicalLayerCC1101(RfDataLinkLayer& rfDataLinkLayer, Platform& platform)
: _rfDataLinkLayer(rfDataLinkLayer),
_platform(platform)
{
}
void RfPhysicalLayer::manchEncode(uint8_t *uncodedData, uint8_t *encodedData)
void RfPhysicalLayerCC1101::manchEncode(uint8_t *uncodedData, uint8_t *encodedData)
{
uint8_t data0, data1;
@ -150,7 +150,7 @@ void RfPhysicalLayer::manchEncode(uint8_t *uncodedData, uint8_t *encodedData)
*(encodedData + 1) = manchEncodeTab[data0];
}
bool RfPhysicalLayer::manchDecode(uint8_t *encodedData, uint8_t *decodedData)
bool RfPhysicalLayerCC1101::manchDecode(uint8_t *encodedData, uint8_t *decodedData)
{
uint8_t data0, data1, data2, data3;
@ -174,7 +174,7 @@ bool RfPhysicalLayer::manchDecode(uint8_t *encodedData, uint8_t *decodedData)
return true;
}
uint8_t RfPhysicalLayer::sIdle()
uint8_t RfPhysicalLayerCC1101::sIdle()
{
uint8_t marcState;
uint32_t timeStart;
@ -200,7 +200,7 @@ uint8_t RfPhysicalLayer::sIdle()
return true;
}
uint8_t RfPhysicalLayer::sReceive()
uint8_t RfPhysicalLayerCC1101::sReceive()
{
uint8_t marcState;
uint32_t timeStart;
@ -226,7 +226,7 @@ uint8_t RfPhysicalLayer::sReceive()
return true;
}
void RfPhysicalLayer::spiWriteRegister(uint8_t spi_instr, uint8_t value)
void RfPhysicalLayerCC1101::spiWriteRegister(uint8_t spi_instr, uint8_t value)
{
uint8_t tbuf[2] = {0};
tbuf[0] = spi_instr | WRITE_SINGLE_BYTE;
@ -237,7 +237,7 @@ void RfPhysicalLayer::spiWriteRegister(uint8_t spi_instr, uint8_t value)
digitalWrite(SPI_SS_PIN, HIGH);
}
uint8_t RfPhysicalLayer::spiReadRegister(uint8_t spi_instr)
uint8_t RfPhysicalLayerCC1101::spiReadRegister(uint8_t spi_instr)
{
uint8_t value;
uint8_t rbuf[2] = {0};
@ -252,7 +252,7 @@ uint8_t RfPhysicalLayer::spiReadRegister(uint8_t spi_instr)
return value;
}
uint8_t RfPhysicalLayer::spiWriteStrobe(uint8_t spi_instr)
uint8_t RfPhysicalLayerCC1101::spiWriteStrobe(uint8_t spi_instr)
{
uint8_t tbuf[1] = {0};
tbuf[0] = spi_instr;
@ -263,7 +263,7 @@ uint8_t RfPhysicalLayer::spiWriteStrobe(uint8_t spi_instr)
return tbuf[0];
}
void RfPhysicalLayer::spiReadBurst(uint8_t spi_instr, uint8_t *pArr, uint8_t len)
void RfPhysicalLayerCC1101::spiReadBurst(uint8_t spi_instr, uint8_t *pArr, uint8_t len)
{
uint8_t rbuf[len + 1];
rbuf[0] = spi_instr | READ_BURST;
@ -277,7 +277,7 @@ void RfPhysicalLayer::spiReadBurst(uint8_t spi_instr, uint8_t *pArr, uint8_t len
}
}
void RfPhysicalLayer::spiWriteBurst(uint8_t spi_instr, const uint8_t *pArr, uint8_t len)
void RfPhysicalLayerCC1101::spiWriteBurst(uint8_t spi_instr, const uint8_t *pArr, uint8_t len)
{
uint8_t tbuf[len + 1];
tbuf[0] = spi_instr | WRITE_BURST;
@ -291,7 +291,7 @@ void RfPhysicalLayer::spiWriteBurst(uint8_t spi_instr, const uint8_t *pArr, uint
digitalWrite(SPI_SS_PIN, HIGH);
}
void RfPhysicalLayer::powerDownCC1101()
void RfPhysicalLayerCC1101::powerDownCC1101()
{
// Set IDLE state first
sIdle();
@ -300,7 +300,7 @@ void RfPhysicalLayer::powerDownCC1101()
spiWriteStrobe(SPWD);
}
void RfPhysicalLayer::setOutputPowerLevel(int8_t dBm)
void RfPhysicalLayerCC1101::setOutputPowerLevel(int8_t dBm)
{
uint8_t pa = 0xC0;
@ -316,7 +316,7 @@ void RfPhysicalLayer::setOutputPowerLevel(int8_t dBm)
spiWriteRegister(FREND0, pa);
}
bool RfPhysicalLayer::InitChip()
bool RfPhysicalLayerCC1101::InitChip()
{
// Setup SPI and GPIOs
_platform.setupSpi();
@ -382,14 +382,14 @@ bool RfPhysicalLayer::InitChip()
return true;
}
void RfPhysicalLayer::stopChip()
void RfPhysicalLayerCC1101::stopChip()
{
powerDownCC1101();
_platform.closeSpi();
}
void RfPhysicalLayer::showRegisterSettings()
void RfPhysicalLayerCC1101::showRegisterSettings()
{
uint8_t config_reg_verify[CFG_REGISTER];
uint8_t Patable_verify[CFG_REGISTER];
@ -404,7 +404,7 @@ void RfPhysicalLayer::showRegisterSettings()
printHex("", Patable_verify, 8);
}
void RfPhysicalLayer::loop()
void RfPhysicalLayerCC1101::loop()
{
switch (_loopState)
{

View File

@ -0,0 +1,246 @@
#pragma once
#include "config.h"
#ifdef USE_RF
#include <stdint.h>
#include "rf_physical_layer.h"
/*----------------------------------[standard]--------------------------------*/
#define CC1101_TIMEOUT 2000 // Time to wait for a response from CC1101
#define RX_PACKET_TIMEOUT 20 // Wait 20ms for packet reception to complete
#define TX_PACKET_TIMEOUT 20 // Wait 20ms for packet reception to complete
#ifdef __linux__ // Linux Platform
extern void delayMicroseconds (unsigned int howLong);
#endif
/*----------------------[CC1101 - misc]---------------------------------------*/
#define CRYSTAL_FREQUENCY 26000000
#define CFG_REGISTER 0x2F //47 registers
#define FIFOBUFFER 0x42 //size of Fifo Buffer +2 for rssi and lqi
#define RSSI_OFFSET_868MHZ 0x4E //dec = 74
#define TX_RETRIES_MAX 0x05 //tx_retries_max
#define ACK_TIMEOUT 250 //ACK timeout in ms
#define CC1101_COMPARE_REGISTER 0x00 //register compare 0=no compare 1=compare
#define BROADCAST_ADDRESS 0x00 //broadcast address
#define CC1101_FREQ_315MHZ 0x01
#define CC1101_FREQ_434MHZ 0x02
#define CC1101_FREQ_868MHZ 0x03
#define CC1101_FREQ_915MHZ 0x04
#define CC1101_TEMP_ADC_MV 3.225 //3.3V/1023 . mV pro digit
#define CC1101_TEMP_CELS_CO 2.47 //Temperature coefficient 2.47mV per Grad Celsius
/*---------------------------[CC1101 - R/W offsets]---------------------------*/
#define WRITE_SINGLE_BYTE 0x00
#define WRITE_BURST 0x40
#define READ_SINGLE_BYTE 0x80
#define READ_BURST 0xC0
/*---------------------------[END R/W offsets]--------------------------------*/
/*------------------------[CC1101 - FIFO commands]----------------------------*/
#define TXFIFO_BURST 0x7F //write burst only
#define TXFIFO_SINGLE_BYTE 0x3F //write single only
#define RXFIFO_BURST 0xFF //read burst only
#define RXFIFO_SINGLE_BYTE 0xBF //read single only
#define PATABLE_BURST 0x7E //power control read/write
#define PATABLE_SINGLE_BYTE 0xFE //power control read/write
/*---------------------------[END FIFO commands]------------------------------*/
/*----------------------[CC1101 - config register]----------------------------*/
#define IOCFG2 0x00 // GDO2 output pin configuration
#define IOCFG1 0x01 // GDO1 output pin configuration
#define IOCFG0 0x02 // GDO0 output pin configuration
#define FIFOTHR 0x03 // RX FIFO and TX FIFO thresholds
#define SYNC1 0x04 // Sync word, high byte
#define SYNC0 0x05 // Sync word, low byte
#define PKTLEN 0x06 // Packet length
#define PKTCTRL1 0x07 // Packet automation control
#define PKTCTRL0 0x08 // Packet automation control
#define DEVADDR 0x09 // Device address
#define CHANNR 0x0A // Channel number
#define FSCTRL1 0x0B // Frequency synthesizer control
#define FSCTRL0 0x0C // Frequency synthesizer control
#define FREQ2 0x0D // Frequency control word, high byte
#define FREQ1 0x0E // Frequency control word, middle byte
#define FREQ0 0x0F // Frequency control word, low byte
#define MDMCFG4 0x10 // Modem configuration
#define MDMCFG3 0x11 // Modem configuration
#define MDMCFG2 0x12 // Modem configuration
#define MDMCFG1 0x13 // Modem configuration
#define MDMCFG0 0x14 // Modem configuration
#define DEVIATN 0x15 // Modem deviation setting
#define MCSM2 0x16 // Main Radio Cntrl State Machine config
#define MCSM1 0x17 // Main Radio Cntrl State Machine config
#define MCSM0 0x18 // Main Radio Cntrl State Machine config
#define FOCCFG 0x19 // Frequency Offset Compensation config
#define BSCFG 0x1A // Bit Synchronization configuration
#define AGCCTRL2 0x1B // AGC control
#define AGCCTRL1 0x1C // AGC control
#define AGCCTRL0 0x1D // AGC control
#define WOREVT1 0x1E // High byte Event 0 timeout
#define WOREVT0 0x1F // Low byte Event 0 timeout
#define WORCTRL 0x20 // Wake On Radio control
#define FREND1 0x21 // Front end RX configuration
#define FREND0 0x22 // Front end TX configuration
#define FSCAL3 0x23 // Frequency synthesizer calibration
#define FSCAL2 0x24 // Frequency synthesizer calibration
#define FSCAL1 0x25 // Frequency synthesizer calibration
#define FSCAL0 0x26 // Frequency synthesizer calibration
#define RCCTRL1 0x27 // RC oscillator configuration
#define RCCTRL0 0x28 // RC oscillator configuration
#define FSTEST 0x29 // Frequency synthesizer cal control
#define PTEST 0x2A // Production test
#define AGCTEST 0x2B // AGC test
#define TEST2 0x2C // Various test settings
#define TEST1 0x2D // Various test settings
#define TEST0 0x2E // Various test settings
/*-------------------------[END config register]------------------------------*/
/*------------------------[CC1101-command strobes]----------------------------*/
#define SRES 0x30 // Reset chip
#define SFSTXON 0x31 // Enable/calibrate freq synthesizer
#define SXOFF 0x32 // Turn off crystal oscillator.
#define SCAL 0x33 // Calibrate freq synthesizer & disable
#define SRX 0x34 // Enable RX.
#define STX 0x35 // Enable TX.
#define SIDLE 0x36 // Exit RX / TX
#define SAFC 0x37 // AFC adjustment of freq synthesizer
#define SWOR 0x38 // Start automatic RX polling sequence
#define SPWD 0x39 // Enter pwr down mode when CSn goes hi
#define SFRX 0x3A // Flush the RX FIFO buffer.
#define SFTX 0x3B // Flush the TX FIFO buffer.
#define SWORRST 0x3C // Reset real time clock.
#define SNOP 0x3D // No operation.
/*-------------------------[END command strobes]------------------------------*/
/*----------------------[CC1101 - status register]----------------------------*/
#define PARTNUM 0xF0 // Part number
#define VERSION 0xF1 // Current version number
#define FREQEST 0xF2 // Frequency offset estimate
#define LQI 0xF3 // Demodulator estimate for link quality
#define RSSI 0xF4 // Received signal strength indication
#define MARCSTATE 0xF5 // Control state machine state
#define WORTIME1 0xF6 // High byte of WOR timer
#define WORTIME0 0xF7 // Low byte of WOR timer
#define PKTSTATUS 0xF8 // Current GDOx status and packet status
#define VCO_VC_DAC 0xF9 // Current setting from PLL cal module
#define TXBYTES 0xFA // Underflow and # of bytes in TXFIFO
#define RXBYTES 0xFB // Overflow and # of bytes in RXFIFO
#define RCCTRL1_STATUS 0xFC //Last RC Oscillator Calibration Result
#define RCCTRL0_STATUS 0xFD //Last RC Oscillator Calibration Result
//--------------------------[END status register]-------------------------------
/*----------------------[CC1101 - Main Radio Control State Machine states]-----*/
#define MARCSTATE_BITMASK 0x1F
#define MARCSTATE_SLEEP 0x00
#define MARCSTATE_IDLE 0x01
#define MARCSTATE_XOFF 0x02
#define MARCSTATE_VCOON_MC 0x03
#define MARCSTATE_REGON_MC 0x04
#define MARCSTATE_MANCAL 0x05
#define MARCSTATE_VCOON 0x06
#define MARCSTATE_REGON 0x07
#define MARCSTATE_STARTCAL 0x08
#define MARCSTATE_BWBOOST 0x09
#define MARCSTATE_FS_LOCK 0x0A
#define MARCSTATE_IFADCON 0x0B
#define MARCSTATE_ENDCAL 0x0C
#define MARCSTATE_RX 0x0D
#define MARCSTATE_RX_END 0x0E
#define MARCSTATE_RX_RST 0x0F
#define MARCSTATE_TXRX_SWITCH 0x10
#define MARCSTATE_RXFIFO_OVERFLOW 0x11
#define MARCSTATE_FSTXON 0x12
#define MARCSTATE_TX 0x13
#define MARCSTATE_TX_END 0x14
#define MARCSTATE_RXTX_SWITCH 0x15
#define MARCSTATE_TXFIFO_UNDERFLOW 0x16
// Chip Status Byte
// Bit fields in the chip status byte
#define CHIPSTATUS_CHIP_RDYn_BITMASK 0x80
#define CHIPSTATUS_STATE_BITMASK 0x70
#define CHIPSTATUS_FIFO_BYTES_AVAILABLE_BITMASK 0x0F
// Chip states
#define CHIPSTATUS_STATE_IDLE 0x00
#define CHIPSTATUS_STATE_RX 0x10
#define CHIPSTATUS_STATE_TX 0x20
#define CHIPSTATUS_STATE_FSTXON 0x30
#define CHIPSTATUS_STATE_CALIBRATE 0x40
#define CHIPSTATUS_STATE_SETTLING 0x50
#define CHIPSTATUS_STATE_RX_OVERFLOW 0x60
#define CHIPSTATUS_STATE_TX_UNDERFLOW 0x70
// loop states
#define RX_START 0
#define RX_ACTIVE 1
#define RX_END 2
#define TX_START 3
#define TX_ACTIVE 4
#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 RfPhysicalLayerCC1101 : public RfPhysicalLayer
{
public:
RfPhysicalLayerCC1101(RfDataLinkLayer& rfDataLinkLayer, Platform& platform);
bool InitChip();
void showRegisterSettings();
void stopChip();
void loop();
private:
// Table for encoding 4-bit data into a 8-bit Manchester encoding.
static const uint8_t manchEncodeTab[16];
// Table for decoding 4-bit Manchester encoded data into 2-bit
static const uint8_t manchDecodeTab[16];
static const uint8_t cc1101_2FSK_32_7_kb[CFG_REGISTER];
static const uint8_t paTablePower868[8];
void manchEncode(uint8_t *uncodedData, uint8_t *encodedData);
bool manchDecode(uint8_t *encodedData, uint8_t *decodedData);
void powerDownCC1101();
void setOutputPowerLevel(int8_t dBm);
uint8_t sIdle();
uint8_t sReceive();
void spiWriteRegister(uint8_t spi_instr, uint8_t value);
uint8_t spiReadRegister(uint8_t spi_instr);
uint8_t spiWriteStrobe(uint8_t spi_instr);
void spiReadBurst(uint8_t spi_instr, uint8_t *pArr, uint8_t len);
void spiWriteBurst(uint8_t spi_instr, const uint8_t *pArr, uint8_t len);
uint8_t _loopState = RX_START;
bool syncStart = false;
bool packetStart = true;
bool fixedLengthMode = false;
uint8_t *sendBuffer {0};
uint16_t sendBufferLength {0};
uint8_t packet[512];
uint8_t buffer[sizeof(packet)*2]; // We need twice the space due to manchester encoding
uint8_t* pByteIndex = &buffer[0];
uint16_t pktLen {0};
uint16_t bytesLeft = {0};
uint8_t statusGDO0 {0};
uint8_t statusGDO2 {0};
uint8_t prevStatusGDO0 {0}; // for edge detection during polling
uint8_t prevStatusGDO2 {0}; // for edge detection during polling
uint32_t packetStartTime {0};
RfDataLinkLayer& _rfDataLinkLayer;
Platform& _platform;
};
#endif

View File

@ -5,7 +5,7 @@
#include <stdio.h>
#include <string.h>
#include "rf_physical_layer.h"
#include "rf_physical_layer_cc1310.h"
#include "rf_data_link_layer.h"
#include <ti/devices/DeviceFamily.h>
@ -36,39 +36,47 @@ static rfc_propRxOutput_t rxStatistics;
static uint8_t packetLength;
static uint8_t* packetDataPointer;
static int32_t packetStartTime;
static int32_t packetStartTime = 0;
static volatile int rf_done, rf_err, err;
int8_t len1, len2;
static volatile bool rfDone = false;
static volatile int rfErr = 0;
static volatile int err;
static void RxCallback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
{
if (e & RF_EventNDataWritten)
if ((e & RF_EventNDataWritten) /*&& (packetStartTime == 0)*/)
{
// pDataEntry->rxData contains the first byte of the received packet.
// Just get the address to get the start address of the receive buffer
uint8_t *pData = &pDataEntry->rxData;
if ((pData[1] != 0x44) || (pData[2] != 0xFF))
{
// cancel early because it does not seem to be KNX RF packet
RF_cancelCmd(rfHandle, rxCommandHandle, 0 /*stop gracefully*/);
RF_cancelCmd(rfHandle, rxCommandHandle, 0 /* force abort RF */);
return;
}
//uint8_t len = rxBuffer[sizeof(rfc_dataEntryPartial_t) + 0];
uint8_t len = pDataEntry->rxData;
struct rfc_CMD_PROP_SET_LEN_s RF_cmdPropSetLen =
{
.commandNo = CMD_PROP_SET_LEN, // command identifier
.rxLen = (uint16_t)PACKET_SIZE(len)
.commandNo = CMD_PROP_SET_LEN, // command identifier
.rxLen = (uint16_t)PACKET_SIZE(len) // packet length to set
};
len1=len; len2 = RF_cmdPropSetLen.rxLen;
//RF_runImmediateCmd(rfHandle, (uint32_t*)&RF_cmdPropSetLen); // for length > 255
RF_runDirectCmd(rfHandle, (uint32_t)&RF_cmdPropSetLen);
RF_Stat status = RF_runDirectCmd(rfHandle, (uint32_t)&RF_cmdPropSetLen);
if (status != RF_StatCmdDoneSuccess)
{
println("RF CMD_PROP_SET_LEN failed!");
}
packetStartTime = millis();
}
else if (e & RF_TERMINATION_EVENT_MASK)
{
rf_done = true;
rf_err = e & (RF_EventCmdStopped | RF_EventCmdAborted | RF_EventCmdCancelled);
rfDone = true;
rfErr = e & (RF_EventCmdStopped | RF_EventCmdAborted | RF_EventCmdCancelled);
}
else /* unknown reason - should not occure */
@ -79,13 +87,12 @@ static void RxCallback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
}
RfPhysicalLayer::RfPhysicalLayer(RfDataLinkLayer& rfDataLinkLayer, Platform& platform)
: _rfDataLinkLayer(rfDataLinkLayer),
_platform(platform)
{
RfPhysicalLayerCC1310::RfPhysicalLayerCC1310(RfDataLinkLayer& rfDataLinkLayer, Platform& platform)
: RfPhysicalLayer(rfDataLinkLayer, platform)
{
}
void RfPhysicalLayer::setOutputPowerLevel(int8_t dBm)
void RfPhysicalLayerCC1310::setOutputPowerLevel(int8_t dBm)
{
RF_TxPowerTable_Entry *rfPowerTable = NULL;
RF_TxPowerTable_Value newValue;
@ -127,14 +134,14 @@ void RfPhysicalLayer::setOutputPowerLevel(int8_t dBm)
}
bool RfPhysicalLayer::InitChip()
bool RfPhysicalLayerCC1310::InitChip()
{
RF_Params rfParams;
RF_Params_init(&rfParams);
pDataEntry->length = 255;
pDataEntry->config.type = DATA_ENTRY_TYPE_PARTIAL; // --> DATA_ENTRY_TYPE_PARTIAL adds a 12 Byte Header
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)
pDataEntry-> config.irqIntv = 3; // KNX-RF first block consists of 12 bytes (one length byte, 0x44, 0xFF, one RFinfo byte, six Serial/DoA bytes, two CRC bytes)
pDataEntry-> config.lenSz = 0; // no length indicator at beginning of data entry
pDataEntry->status = DATA_ENTRY_PENDING;
pDataEntry->pNextEntry = (uint8_t*)pDataEntry;
@ -154,11 +161,11 @@ bool RfPhysicalLayer::InitChip()
rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);
/* Set the frequency */
RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
RF_runCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
return true;
}
void RfPhysicalLayer::stopChip()
void RfPhysicalLayerCC1310::stopChip()
{
RF_cancelCmd(rfHandle, rxCommandHandle, 0 /* do not stop gracefully, instead hard abort RF */);
RF_pendCmd(rfHandle, rxCommandHandle, RF_TERMINATION_EVENT_MASK);
@ -166,7 +173,7 @@ void RfPhysicalLayer::stopChip()
RF_close(rfHandle);
}
void RfPhysicalLayer::loop()
void RfPhysicalLayerCC1310::loop()
{
switch (_loopState)
{
@ -175,10 +182,14 @@ void RfPhysicalLayer::loop()
println("TX_START...");
_rfDataLinkLayer.loadNextTxFrame(&sendBuffer, &sendBufferLength);
pktLen = PACKET_SIZE(sendBuffer[0]);
if (pktLen != sendBufferLength)
{
printf("Error: SendBuffer[0]=%d, SendBufferLength=%d PACKET_SIZE=%d\n", sendBuffer[0], sendBufferLength, PACKET_SIZE(sendBuffer[0]));
print("Error TX: SendBuffer[0]=");println(sendBuffer[0]);
print("Error TX: SendBufferLength=");println(sendBufferLength);
print("Error TX: PACKET_SIZE=");println(PACKET_SIZE(sendBuffer[0]));
}
// Calculate total number of bytes in the KNX RF packet from L-field
// Check for valid length
if ((pktLen == 0) || (pktLen > 290))
@ -193,16 +204,16 @@ void RfPhysicalLayer::loop()
break;
}
RF_cmdPropTx.pktLen = pktLen;
RF_cmdPropTx.pPkt = sendBuffer;
RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;
RF_EventMask res = RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal, NULL, RF_TERMINATION_EVENT_MASK);
RF_cmdPropTx.pktLen = pktLen;
RF_cmdPropTx.pPkt = sendBuffer;
RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;
RF_EventMask result = RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal, NULL, RF_TERMINATION_EVENT_MASK);
delete sendBuffer;
if (res != RF_EventLastCmdDone)
if (result != RF_EventLastCmdDone)
{
printf("Unexpected result command %llu\n", res);
print("Unexpected result command: ");println(result, HEX);
}
_loopState = RX_START;
@ -211,81 +222,78 @@ void RfPhysicalLayer::loop()
case RX_START:
{
rf_done = rf_err = false;
err = 0;
packetStartTime = 0;
rfDone = false;
rfErr = 0;
err = 0;
pDataEntry->status = DATA_ENTRY_PENDING;
rxCommandHandle = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRxAdv, RF_PriorityNormal, &RxCallback, IRQ_RX_N_DATA_WRITTEN);
if (rxCommandHandle == RF_ALLOC_ERROR)
{
println("Error: nRF_pendCmd() failed");
return;
}
rxCommandHandle = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRxAdv, RF_PriorityNormal, &RxCallback, IRQ_RX_N_DATA_WRITTEN);
if (rxCommandHandle == RF_ALLOC_ERROR)
{
println("Error: nRF_pendCmd() failed");
return;
}
_loopState = RX_ACTIVE;
}
break;
case RX_ACTIVE:
{
if (!_rfDataLinkLayer.isTxQueueEmpty() && !syncStart)
if (!_rfDataLinkLayer.isTxQueueEmpty())
{
RF_cancelCmd(rfHandle, rxCommandHandle, RF_ABORT_GRACEFULLY);
RF_pendCmd(rfHandle, rxCommandHandle, RF_TERMINATION_EVENT_MASK);
pDataEntry->status = DATA_ENTRY_PENDING;
_loopState = TX_START;
break;
}
// Check if we have an incomplete packet reception
if (!rf_done && syncStart && (millis() - packetStartTime > RX_PACKET_TIMEOUT))
if (!rfDone && ((packetStartTime > 0) && (millis() - packetStartTime > RX_PACKET_TIMEOUT)))
{
println("RX packet timeout!");
RF_cancelCmd(rfHandle, rxCommandHandle, RF_ABORT_GRACEFULLY);
RF_pendCmd(rfHandle, rxCommandHandle, RF_TERMINATION_EVENT_MASK);
pDataEntry->status = DATA_ENTRY_PENDING;
_loopState = RX_START;
break;
}
else if (rf_done)
else if (rfDone)
{
RF_EventMask res = RF_pendCmd(rfHandle, rxCommandHandle, RF_TERMINATION_EVENT_MASK);
if (res == RF_EventCmdCancelled || res == RF_EventCmdStopped || res == RF_EventCmdAborted)
RF_EventMask result = RF_pendCmd(rfHandle, rxCommandHandle, RF_TERMINATION_EVENT_MASK);
if ((result & RF_EventCmdCancelled) || (result & RF_EventCmdStopped) || (result & RF_EventCmdAborted))
{
println("RF terminated because of RF_flushCmd() or RF_cancelCmd()");
}
else if (res != RF_EventLastCmdDone)
else if ((result & RF_EventLastCmdDone) != RF_EventLastCmdDone)
{
//printf("Unexpected Rx result command %llu\n", res);
print("Unexpected Rx result command: ");
println(res, HEX);
print("Unexpected Rx result command: ");println(result, HEX);
}
else if (rf_err)
else if (rfErr)
{
println("Rx is no KNX frame");
}
else
{
//printf("len1=%d, len1=%d, frags=%d, err=%d\n", len1, len2, frags, err);
print("nRxOk = ");println(rxStatistics.nRxOk); //!< Number of packets that have been received with payload, CRC OK and not ignored
print("nRxNok = ");println(rxStatistics.nRxNok); //!< Number of packets that have been received with CRC error
print("nRxIgnored = ");println(rxStatistics.nRxIgnored); //!< Number of packets that have been received with CRC OK and ignored due to address mismatch
print("nRxStopped = ");println(rxStatistics.nRxStopped); //!< Number of packets not received due to illegal length or address mismatch with pktConf.filterOp = 1
print("nRxBufFull = ");println(rxStatistics.nRxBufFull); //!< Number of packets that have been received and discarded due to lack of buffer space
print("lastRssi = ");println(rxStatistics.lastRssi); //!< RSSI of last received packet
print("nRxOk = ");println(rxStatistics.nRxOk); // Number of packets that have been received with payload, CRC OK and not ignored
print("nRxNok = ");println(rxStatistics.nRxNok); // Number of packets that have been received with CRC error
print("nRxIgnored = ");println(rxStatistics.nRxIgnored); // Number of packets that have been received with CRC OK and ignored due to address mismatch
print("nRxStopped = ");println(rxStatistics.nRxStopped); // Number of packets not received due to illegal length or address mismatch with pktConf.filterOp = 1
print("nRxBufFull = ");println(rxStatistics.nRxBufFull); // Number of packets that have been received and discarded due to lack of buffer space
print("lastRssi = ");println(rxStatistics.lastRssi); // RSSI of last received packet
// add CRC sizes for received blocks, but do not add the length of the L-field (1 byte) itself
packetLength = PACKET_SIZE(pDataEntry->rxData);
packetDataPointer = (uint8_t *) &pDataEntry->rxData;
if (packetLength+1 != pDataEntry->nextIndex)
if (packetLength != (pDataEntry->nextIndex - 1))
{
//printf("Size mismatch: %d %d\n", packetLength, *(uint8_t *)(&(currentDataEntry->data)+2));
//printf("Size mismatch: %d %d\n", packetLength, pDataEntry->nextIndex);
println("Size mismatch");
println("Mismatch between packetLength and pDataEntry->nextIndex: ");
print("packetLength = ");print(packetLength);
print(", pDataEntry->nextIndex = ");println(pDataEntry->nextIndex);
}
printHex("RX: ", packetDataPointer, packetLength);
_rfDataLinkLayer.frameBytesReceived(packetDataPointer, packetLength);
pDataEntry->status = DATA_ENTRY_PENDING;
}
_loopState = RX_START;
}

View File

@ -0,0 +1,44 @@
#pragma once
#include "config.h"
#ifdef USE_RF
#include <stdint.h>
#include "rf_physical_layer.h"
#define RX_PACKET_TIMEOUT 20 // Wait 20ms for packet reception to complete
// 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*/)
// loop states
#define RX_START 0
#define RX_ACTIVE 1
#define RX_END 2
#define TX_START 3
#define TX_ACTIVE 4
#define TX_END 5
class RfDataLinkLayer;
class RfPhysicalLayerCC1310 : public RfPhysicalLayer
{
public:
RfPhysicalLayerCC1310(RfDataLinkLayer& rfDataLinkLayer, Platform& platform);
virtual bool InitChip() override;
virtual void stopChip() override;
virtual void loop() override;
void setOutputPowerLevel(int8_t dBm);
private:
uint16_t pktLen {0};
uint8_t *sendBuffer {0};
uint16_t sendBufferLength {0};
uint8_t _loopState = RX_START;
};
#endif