From 876872524692cb5d0cae2092b21e74581661f63a Mon Sep 17 00:00:00 2001 From: Nanosonde <2073569+nanosonde@users.noreply.github.com> Date: Wed, 4 Nov 2020 16:08:58 +0100 Subject: [PATCH] continue cleanup --- examples/knx-cc1310/CMakeLists.txt | 1 + src/knx/bau27B0.h | 6 +- src/knx/rf_data_link_layer.cpp | 6 +- src/knx/rf_data_link_layer.h | 15 +- src/knx/rf_physical_layer.h | 228 +--------------- ...layer.cpp => rf_physical_layer_cc1101.cpp} | 42 +-- src/knx/rf_physical_layer_cc1101.h | 246 ++++++++++++++++++ src/knx/rf_physical_layer_cc1310.cpp | 132 +++++----- src/knx/rf_physical_layer_cc1310.h | 44 ++++ 9 files changed, 408 insertions(+), 312 deletions(-) rename src/knx/{rf_physical_layer.cpp => rf_physical_layer_cc1101.cpp} (95%) create mode 100644 src/knx/rf_physical_layer_cc1101.h create mode 100644 src/knx/rf_physical_layer_cc1310.h diff --git a/examples/knx-cc1310/CMakeLists.txt b/examples/knx-cc1310/CMakeLists.txt index 78ce6b5..41b73a4 100644 --- a/examples/knx-cc1310/CMakeLists.txt +++ b/examples/knx-cc1310/CMakeLists.txt @@ -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 diff --git a/src/knx/bau27B0.h b/src/knx/bau27B0.h index 8659fac..4d8b7fc 100644 --- a/src/knx/bau27B0.h +++ b/src/knx/bau27B0.h @@ -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" diff --git a/src/knx/rf_data_link_layer.cpp b/src/knx/rf_data_link_layer.cpp index fb3b3be..a573ce1 100644 --- a/src/knx/rf_data_link_layer.cpp +++ b/src/knx/rf_data_link_layer.cpp @@ -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" diff --git a/src/knx/rf_data_link_layer.h b/src/knx/rf_data_link_layer.h index 849d12a..f085065 100644 --- a/src/knx/rf_data_link_layer.h +++ b/src/knx/rf_data_link_layer.h @@ -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(); diff --git a/src/knx/rf_physical_layer.h b/src/knx/rf_physical_layer.h index d39f4db..6b2828b 100644 --- a/src/knx/rf_physical_layer.h +++ b/src/knx/rf_physical_layer.h @@ -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; }; diff --git a/src/knx/rf_physical_layer.cpp b/src/knx/rf_physical_layer_cc1101.cpp similarity index 95% rename from src/knx/rf_physical_layer.cpp rename to src/knx/rf_physical_layer_cc1101.cpp index 8997024..b58b721 100644 --- a/src/knx/rf_physical_layer.cpp +++ b/src/knx/rf_physical_layer_cc1101.cpp @@ -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) { diff --git a/src/knx/rf_physical_layer_cc1101.h b/src/knx/rf_physical_layer_cc1101.h new file mode 100644 index 0000000..e8e0d94 --- /dev/null +++ b/src/knx/rf_physical_layer_cc1101.h @@ -0,0 +1,246 @@ +#pragma once + +#include "config.h" +#ifdef USE_RF + +#include + +#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 diff --git a/src/knx/rf_physical_layer_cc1310.cpp b/src/knx/rf_physical_layer_cc1310.cpp index b8e8b64..6846543 100644 --- a/src/knx/rf_physical_layer_cc1310.cpp +++ b/src/knx/rf_physical_layer_cc1310.cpp @@ -5,7 +5,7 @@ #include #include -#include "rf_physical_layer.h" +#include "rf_physical_layer_cc1310.h" #include "rf_data_link_layer.h" #include @@ -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; } diff --git a/src/knx/rf_physical_layer_cc1310.h b/src/knx/rf_physical_layer_cc1310.h new file mode 100644 index 0000000..06ffea7 --- /dev/null +++ b/src/knx/rf_physical_layer_cc1310.h @@ -0,0 +1,44 @@ +#pragma once + +#include "config.h" +#ifdef USE_RF + +#include + +#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