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.cpp
../../src/knx/rf_medium_object.h ../../src/knx/rf_medium_object.h
../../src/knx/rf_physical_layer_cc1310.cpp ../../src/knx/rf_physical_layer_cc1310.cpp
../../src/knx/rf_physical_layer_cc1310.h
../../src/knx/rf_physical_layer.h ../../src/knx/rf_physical_layer.h
../../src/knx/router_object.cpp ../../src/knx/router_object.cpp
../../src/knx/router_object.h ../../src/knx/router_object.h

View File

@ -5,7 +5,11 @@
#include "bau_systemB_device.h" #include "bau_systemB_device.h"
#include "rf_medium_object.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 "rf_data_link_layer.h"
#include "cemi_server.h" #include "cemi_server.h"
#include "cemi_server_object.h" #include "cemi_server_object.h"

View File

@ -1,7 +1,11 @@
#include "config.h" #include "config.h"
#ifdef USE_RF #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 "rf_data_link_layer.h"
#include "bits.h" #include "bits.h"

View File

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

View File

@ -7,181 +7,6 @@
#include "platform.h" #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 // 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*/) #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 class RfPhysicalLayer
{ {
public: public:
RfPhysicalLayer(RfDataLinkLayer& rfDataLinkLayer, Platform& platform); RfPhysicalLayer(RfDataLinkLayer& rfDataLinkLayer, Platform& platform)
: _rfDataLinkLayer(rfDataLinkLayer), _platform(platform) {}
bool InitChip(); virtual bool InitChip() = 0;
void showRegisterSettings(); virtual void stopChip() = 0;
void stopChip(); virtual void loop() = 0;
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};
protected:
RfDataLinkLayer& _rfDataLinkLayer; RfDataLinkLayer& _rfDataLinkLayer;
Platform& _platform; Platform& _platform;
}; };

View File

@ -1,7 +1,7 @@
#include "config.h" #include "config.h"
#ifdef USE_RF #ifdef USE_RF
#include "rf_physical_layer.h" #include "rf_physical_layer_cc1101.h"
#include "rf_data_link_layer.h" #include "rf_data_link_layer.h"
#include "bits.h" #include "bits.h"
@ -15,7 +15,7 @@
#define ABS(x) ((x > 0) ? (x) : (-x)) #define ABS(x) ((x > 0) ? (x) : (-x))
// Table for encoding 4-bit data into a 8-bit Manchester encoding. // 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 0xA9, // 0x1 Manchester encoded
0xA6, // 0x2 Manchester encoded 0xA6, // 0x2 Manchester encoded
0xA5, // 0x3 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 // Table for decoding 4-bit Manchester encoded data into 2-bit
// data. 0xFF indicates invalid Manchester encoding // 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 0x1 decoded
0xFF, // Manchester encoded 0x2 decoded 0xFF, // Manchester encoded 0x2 decoded
0xFF, // Manchester encoded 0x3 decoded 0xFF, // Manchester encoded 0x3 decoded
@ -78,7 +78,7 @@ const uint8_t RfPhysicalLayer::manchDecodeTab[16] = {0xFF, // Manchester encode
// Device address = 0 // Device address = 0
// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at the end of the packet // 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 // 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 0x00, // IOCFG2 GDO2 Output Pin Configuration
0x2E, // IOCFG1 GDO1 Output Pin Configuration 0x2E, // IOCFG1 GDO1 Output Pin Configuration
0x06, // IOCFG0 GDO0 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 //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), : _rfDataLinkLayer(rfDataLinkLayer),
_platform(platform) _platform(platform)
{ {
} }
void RfPhysicalLayer::manchEncode(uint8_t *uncodedData, uint8_t *encodedData) void RfPhysicalLayerCC1101::manchEncode(uint8_t *uncodedData, uint8_t *encodedData)
{ {
uint8_t data0, data1; uint8_t data0, data1;
@ -150,7 +150,7 @@ void RfPhysicalLayer::manchEncode(uint8_t *uncodedData, uint8_t *encodedData)
*(encodedData + 1) = manchEncodeTab[data0]; *(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; uint8_t data0, data1, data2, data3;
@ -174,7 +174,7 @@ bool RfPhysicalLayer::manchDecode(uint8_t *encodedData, uint8_t *decodedData)
return true; return true;
} }
uint8_t RfPhysicalLayer::sIdle() uint8_t RfPhysicalLayerCC1101::sIdle()
{ {
uint8_t marcState; uint8_t marcState;
uint32_t timeStart; uint32_t timeStart;
@ -200,7 +200,7 @@ uint8_t RfPhysicalLayer::sIdle()
return true; return true;
} }
uint8_t RfPhysicalLayer::sReceive() uint8_t RfPhysicalLayerCC1101::sReceive()
{ {
uint8_t marcState; uint8_t marcState;
uint32_t timeStart; uint32_t timeStart;
@ -226,7 +226,7 @@ uint8_t RfPhysicalLayer::sReceive()
return true; 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}; uint8_t tbuf[2] = {0};
tbuf[0] = spi_instr | WRITE_SINGLE_BYTE; 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); 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 value;
uint8_t rbuf[2] = {0}; uint8_t rbuf[2] = {0};
@ -252,7 +252,7 @@ uint8_t RfPhysicalLayer::spiReadRegister(uint8_t spi_instr)
return value; return value;
} }
uint8_t RfPhysicalLayer::spiWriteStrobe(uint8_t spi_instr) uint8_t RfPhysicalLayerCC1101::spiWriteStrobe(uint8_t spi_instr)
{ {
uint8_t tbuf[1] = {0}; uint8_t tbuf[1] = {0};
tbuf[0] = spi_instr; tbuf[0] = spi_instr;
@ -263,7 +263,7 @@ uint8_t RfPhysicalLayer::spiWriteStrobe(uint8_t spi_instr)
return tbuf[0]; 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]; uint8_t rbuf[len + 1];
rbuf[0] = spi_instr | READ_BURST; 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]; uint8_t tbuf[len + 1];
tbuf[0] = spi_instr | WRITE_BURST; 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); digitalWrite(SPI_SS_PIN, HIGH);
} }
void RfPhysicalLayer::powerDownCC1101() void RfPhysicalLayerCC1101::powerDownCC1101()
{ {
// Set IDLE state first // Set IDLE state first
sIdle(); sIdle();
@ -300,7 +300,7 @@ void RfPhysicalLayer::powerDownCC1101()
spiWriteStrobe(SPWD); spiWriteStrobe(SPWD);
} }
void RfPhysicalLayer::setOutputPowerLevel(int8_t dBm) void RfPhysicalLayerCC1101::setOutputPowerLevel(int8_t dBm)
{ {
uint8_t pa = 0xC0; uint8_t pa = 0xC0;
@ -316,7 +316,7 @@ void RfPhysicalLayer::setOutputPowerLevel(int8_t dBm)
spiWriteRegister(FREND0, pa); spiWriteRegister(FREND0, pa);
} }
bool RfPhysicalLayer::InitChip() bool RfPhysicalLayerCC1101::InitChip()
{ {
// Setup SPI and GPIOs // Setup SPI and GPIOs
_platform.setupSpi(); _platform.setupSpi();
@ -382,14 +382,14 @@ bool RfPhysicalLayer::InitChip()
return true; return true;
} }
void RfPhysicalLayer::stopChip() void RfPhysicalLayerCC1101::stopChip()
{ {
powerDownCC1101(); powerDownCC1101();
_platform.closeSpi(); _platform.closeSpi();
} }
void RfPhysicalLayer::showRegisterSettings() void RfPhysicalLayerCC1101::showRegisterSettings()
{ {
uint8_t config_reg_verify[CFG_REGISTER]; uint8_t config_reg_verify[CFG_REGISTER];
uint8_t Patable_verify[CFG_REGISTER]; uint8_t Patable_verify[CFG_REGISTER];
@ -404,7 +404,7 @@ void RfPhysicalLayer::showRegisterSettings()
printHex("", Patable_verify, 8); printHex("", Patable_verify, 8);
} }
void RfPhysicalLayer::loop() void RfPhysicalLayerCC1101::loop()
{ {
switch (_loopState) 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 <stdio.h>
#include <string.h> #include <string.h>
#include "rf_physical_layer.h" #include "rf_physical_layer_cc1310.h"
#include "rf_data_link_layer.h" #include "rf_data_link_layer.h"
#include <ti/devices/DeviceFamily.h> #include <ti/devices/DeviceFamily.h>
@ -36,39 +36,47 @@ 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; static int32_t packetStartTime = 0;
static volatile int rf_done, rf_err, err; static volatile bool rfDone = false;
int8_t len1, len2; static volatile int rfErr = 0;
static volatile int err;
static void RxCallback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e) 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; uint8_t *pData = &pDataEntry->rxData;
if ((pData[1] != 0x44) || (pData[2] != 0xFF)) if ((pData[1] != 0x44) || (pData[2] != 0xFF))
{ {
// cancel early because it does not seem to be KNX RF packet // 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; return;
} }
//uint8_t len = rxBuffer[sizeof(rfc_dataEntryPartial_t) + 0];
uint8_t len = pDataEntry->rxData; 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
.rxLen = (uint16_t)PACKET_SIZE(len) .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_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(); packetStartTime = millis();
} }
else if (e & RF_TERMINATION_EVENT_MASK) else if (e & RF_TERMINATION_EVENT_MASK)
{ {
rf_done = true; rfDone = true;
rf_err = e & (RF_EventCmdStopped | RF_EventCmdAborted | RF_EventCmdCancelled); rfErr = e & (RF_EventCmdStopped | RF_EventCmdAborted | RF_EventCmdCancelled);
} }
else /* unknown reason - should not occure */ 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) RfPhysicalLayerCC1310::RfPhysicalLayerCC1310(RfDataLinkLayer& rfDataLinkLayer, Platform& platform)
: _rfDataLinkLayer(rfDataLinkLayer), : RfPhysicalLayer(rfDataLinkLayer, platform)
_platform(platform)
{ {
} }
void RfPhysicalLayer::setOutputPowerLevel(int8_t dBm) void RfPhysicalLayerCC1310::setOutputPowerLevel(int8_t dBm)
{ {
RF_TxPowerTable_Entry *rfPowerTable = NULL; RF_TxPowerTable_Entry *rfPowerTable = NULL;
RF_TxPowerTable_Value newValue; 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 rfParams;
RF_Params_init(&rfParams); RF_Params_init(&rfParams);
pDataEntry->length = 255; pDataEntry->length = 255;
pDataEntry->config.type = DATA_ENTRY_TYPE_PARTIAL; // --> DATA_ENTRY_TYPE_PARTIAL adds a 12 Byte Header 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-> config.lenSz = 0; // no length indicator at beginning of data entry
pDataEntry->status = DATA_ENTRY_PENDING; pDataEntry->status = DATA_ENTRY_PENDING;
pDataEntry->pNextEntry = (uint8_t*)pDataEntry; pDataEntry->pNextEntry = (uint8_t*)pDataEntry;
@ -154,11 +161,11 @@ bool RfPhysicalLayer::InitChip()
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 */
RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0); RF_runCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
return true; return true;
} }
void RfPhysicalLayer::stopChip() void RfPhysicalLayerCC1310::stopChip()
{ {
RF_cancelCmd(rfHandle, rxCommandHandle, 0 /* do not stop gracefully, instead hard abort RF */); RF_cancelCmd(rfHandle, rxCommandHandle, 0 /* do not stop gracefully, instead hard abort RF */);
RF_pendCmd(rfHandle, rxCommandHandle, RF_TERMINATION_EVENT_MASK); RF_pendCmd(rfHandle, rxCommandHandle, RF_TERMINATION_EVENT_MASK);
@ -166,7 +173,7 @@ void RfPhysicalLayer::stopChip()
RF_close(rfHandle); RF_close(rfHandle);
} }
void RfPhysicalLayer::loop() void RfPhysicalLayerCC1310::loop()
{ {
switch (_loopState) switch (_loopState)
{ {
@ -175,10 +182,14 @@ 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]);
if (pktLen != sendBufferLength) 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 // Calculate total number of bytes in the KNX RF packet from L-field
// Check for valid length // Check for valid length
if ((pktLen == 0) || (pktLen > 290)) if ((pktLen == 0) || (pktLen > 290))
@ -193,16 +204,16 @@ void RfPhysicalLayer::loop()
break; break;
} }
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, RF_TERMINATION_EVENT_MASK); RF_EventMask result = RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal, NULL, RF_TERMINATION_EVENT_MASK);
delete sendBuffer; 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; _loopState = RX_START;
@ -211,81 +222,78 @@ void RfPhysicalLayer::loop()
case RX_START: case RX_START:
{ {
rf_done = rf_err = false; packetStartTime = 0;
err = 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); 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");
return; return;
} }
_loopState = RX_ACTIVE; _loopState = RX_ACTIVE;
} }
break; break;
case RX_ACTIVE: case RX_ACTIVE:
{ {
if (!_rfDataLinkLayer.isTxQueueEmpty() && !syncStart) if (!_rfDataLinkLayer.isTxQueueEmpty())
{ {
RF_cancelCmd(rfHandle, rxCommandHandle, RF_ABORT_GRACEFULLY); RF_cancelCmd(rfHandle, rxCommandHandle, RF_ABORT_GRACEFULLY);
RF_pendCmd(rfHandle, rxCommandHandle, RF_TERMINATION_EVENT_MASK); RF_pendCmd(rfHandle, rxCommandHandle, RF_TERMINATION_EVENT_MASK);
pDataEntry->status = DATA_ENTRY_PENDING;
_loopState = TX_START; _loopState = TX_START;
break; break;
} }
// Check if we have an incomplete packet reception // 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!"); println("RX packet timeout!");
RF_cancelCmd(rfHandle, rxCommandHandle, RF_ABORT_GRACEFULLY); RF_cancelCmd(rfHandle, rxCommandHandle, RF_ABORT_GRACEFULLY);
RF_pendCmd(rfHandle, rxCommandHandle, RF_TERMINATION_EVENT_MASK); RF_pendCmd(rfHandle, rxCommandHandle, RF_TERMINATION_EVENT_MASK);
pDataEntry->status = DATA_ENTRY_PENDING;
_loopState = RX_START; _loopState = RX_START;
break; break;
} }
else if (rf_done) else if (rfDone)
{ {
RF_EventMask res = RF_pendCmd(rfHandle, rxCommandHandle, RF_TERMINATION_EVENT_MASK); RF_EventMask result = RF_pendCmd(rfHandle, rxCommandHandle, RF_TERMINATION_EVENT_MASK);
if (res == RF_EventCmdCancelled || res == RF_EventCmdStopped || res == RF_EventCmdAborted) if ((result & RF_EventCmdCancelled) || (result & RF_EventCmdStopped) || (result & 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 ((result & RF_EventLastCmdDone) != RF_EventLastCmdDone)
{ {
//printf("Unexpected Rx result command %llu\n", res); print("Unexpected Rx result command: ");println(result, HEX);
print("Unexpected Rx result command: ");
println(res, HEX);
} }
else if (rf_err) else if (rfErr)
{ {
println("Rx is no KNX frame"); println("Rx is no KNX frame");
} }
else 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("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("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("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("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("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("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 // add CRC sizes for received blocks, but do not add the length of the L-field (1 byte) itself
packetLength = PACKET_SIZE(pDataEntry->rxData); packetLength = PACKET_SIZE(pDataEntry->rxData);
packetDataPointer = (uint8_t *) &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)); println("Mismatch between packetLength and pDataEntry->nextIndex: ");
//printf("Size mismatch: %d %d\n", packetLength, pDataEntry->nextIndex); print("packetLength = ");print(packetLength);
println("Size mismatch"); print(", pDataEntry->nextIndex = ");println(pDataEntry->nextIndex);
} }
printHex("RX: ", packetDataPointer, packetLength); printHex("RX: ", packetDataPointer, packetLength);
_rfDataLinkLayer.frameBytesReceived(packetDataPointer, packetLength); _rfDataLinkLayer.frameBytesReceived(packetDataPointer, packetLength);
pDataEntry->status = DATA_ENTRY_PENDING;
} }
_loopState = RX_START; _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