diff --git a/knx-linux/CMakeLists.txt b/knx-linux/CMakeLists.txt
index bd7861c..fb1d483 100644
--- a/knx-linux/CMakeLists.txt
+++ b/knx-linux/CMakeLists.txt
@@ -25,8 +25,10 @@ add_executable(knx-linux
../src/knx/bits.cpp
../src/knx/bits.h
../src/knx/callback_property.h
- ../src/knx/cemi_frame.cpp
+ ../src/knx/cemi_frame.cpp
../src/knx/cemi_frame.h
+ ../src/knx/cemi_server.cpp
+ ../src/knx/cemi_server_object.cpp
../src/knx/data_link_layer.cpp
../src/knx/data_link_layer.h
../src/knx/data_property.cpp
@@ -47,6 +49,7 @@ add_executable(knx-linux
../src/knx/ip_data_link_layer.h
../src/knx/ip_parameter_object.cpp
../src/knx/ip_parameter_object.h
+ ../src/knx/knx_ip_frame.cpp
../src/knx/knx_value.cpp
../src/knx/knx_value.h
../src/knx/memory.cpp
@@ -57,14 +60,14 @@ add_executable(knx-linux
../src/knx/npdu.h
../src/knx/platform.cpp
../src/knx/platform.h
+ ../src/knx/property.cpp
+ ../src/knx/property.h
../src/knx/rf_data_link_layer.cpp
../src/knx/rf_data_link_layer.h
../src/knx/rf_medium_object.cpp
../src/knx/rf_medium_object.h
../src/knx/rf_physical_layer.cpp
../src/knx/rf_physical_layer.h
- ../src/knx/property.cpp
- ../src/knx/property.h
../src/knx/table_object.cpp
../src/knx/table_object.h
../src/knx/tpdu.cpp
@@ -73,6 +76,7 @@ add_executable(knx-linux
../src/knx/tpuart_data_link_layer.h
../src/knx/transport_layer.cpp
../src/knx/transport_layer.h
+ ../src/knx/usb_tunnel_interface.cpp
../src/knx_facade.cpp
../src/knx_facade.h
../src/linux_platform.cpp
diff --git a/knx-linux/knx-linux-Debug.vgdbsettings b/knx-linux/knx-linux-Debug.vgdbsettings
index 59c1756..8e4ab7c 100644
--- a/knx-linux/knx-linux-Debug.vgdbsettings
+++ b/knx-linux/knx-linux-Debug.vgdbsettings
@@ -111,7 +111,7 @@
True
- -DMEDIUM_TYPE=5 -DUSE_CEMI_SERVER
+ -DMEDIUM_TYPE=5
true
true
diff --git a/knx-linux/knx-linux.vcxproj b/knx-linux/knx-linux.vcxproj
index effa490..98e8be5 100644
--- a/knx-linux/knx-linux.vcxproj
+++ b/knx-linux/knx-linux.vcxproj
@@ -86,6 +86,7 @@
+
diff --git a/knx-linux/knx-linux.vcxproj.filters b/knx-linux/knx-linux.vcxproj.filters
index dc1b54a..f8de660 100644
--- a/knx-linux/knx-linux.vcxproj.filters
+++ b/knx-linux/knx-linux.vcxproj.filters
@@ -170,6 +170,9 @@
Header files\knx
+
+ Header files\knx
+
diff --git a/knx-linux/main.cpp b/knx-linux/main.cpp
index 13cfc0c..dbca23d 100644
--- a/knx-linux/main.cpp
+++ b/knx-linux/main.cpp
@@ -1,11 +1,9 @@
#include "knx_facade.h"
-#if MEDIUM_TYPE == 5
+
#include "knx/bau57B0.h"
-#elif MEDIUM_TYPE == 2
#include "knx/bau27B0.h"
-#else
-#error Only MEDIUM_TYPE IP and RF supported
-#endif
+#include "knx/bau07B0.h"
+
#include "knx/group_object_table_object.h"
#include "knx/bits.h"
#include
@@ -25,6 +23,14 @@ void signalHandler(int sig)
loopActive = 0;
}
+bool sendHidReport(uint8_t* data, uint16_t length)
+{
+ return false;
+}
+bool isSendHidReportPossible()
+{
+ return false;
+}
#if MEDIUM_TYPE == 5
KnxFacade knx;
#elif MEDIUM_TYPE == 2
@@ -60,7 +66,6 @@ void measureTemp()
if (currentValue > max)
MAX.value(currentValue);
- double min = MIN.value();
if (currentValue < (double)MIN.value())
MIN.value(currentValue);
}
@@ -142,9 +147,10 @@ int main(int argc, char **argv)
// opens the "value" sysfs file to read or write the GPIO pin value.
// The following calls will close the "value" sysfs fiel for the pin
// and unexport the GPIO pin.
+#ifdef USE_RF
gpio_unexport(SPI_SS_PIN);
gpio_unexport(GPIO_GDO2_PIN);
gpio_unexport(GPIO_GDO0_PIN);
-
+#endif
printf("main() exit.\n");
}
diff --git a/src/knx/bau07B0.cpp b/src/knx/bau07B0.cpp
index 9affe2f..0c2a877 100644
--- a/src/knx/bau07B0.cpp
+++ b/src/knx/bau07B0.cpp
@@ -3,6 +3,8 @@
#include
#include
+#ifdef USE_TP
+
using namespace std;
Bau07B0::Bau07B0(Platform& platform)
@@ -98,4 +100,6 @@ void Bau07B0::loop()
#ifdef USE_CEMI_SERVER
_cemiServer.loop();
#endif
-}
\ No newline at end of file
+}
+
+#endif
\ No newline at end of file
diff --git a/src/knx/bau07B0.h b/src/knx/bau07B0.h
index 41934c8..d5099e1 100644
--- a/src/knx/bau07B0.h
+++ b/src/knx/bau07B0.h
@@ -1,10 +1,13 @@
#pragma once
+#include "config.h"
#include "bau_systemB.h"
#include "tpuart_data_link_layer.h"
#include "cemi_server.h"
#include "cemi_server_object.h"
+#ifdef USE_TP
+
class Bau07B0 : public BauSystemB
{
public:
@@ -32,4 +35,5 @@ class Bau07B0 : public BauSystemB
const uint32_t _ifObjs[6] = { 5, // length
OT_DEVICE, OT_ADDR_TABLE, OT_ASSOC_TABLE, OT_GRP_OBJ_TABLE, OT_APPLICATION_PROG};
#endif
-};
\ No newline at end of file
+};
+#endif
\ No newline at end of file
diff --git a/src/knx/bau27B0.h b/src/knx/bau27B0.h
index fdfa615..d76d329 100644
--- a/src/knx/bau27B0.h
+++ b/src/knx/bau27B0.h
@@ -1,5 +1,7 @@
#pragma once
+#include "config.h"
+#ifdef USE_RF
#include "bau_systemB.h"
#include "rf_medium_object.h"
#include "rf_physical_layer.h"
@@ -42,4 +44,5 @@ class Bau27B0 : public BauSystemB
void individualAddressSerialNumberWriteIndication(Priority priority, HopCountType hopType, uint16_t newIndividualAddress,
uint8_t* knxSerialNumber);
void individualAddressSerialNumberReadIndication(Priority priority, HopCountType hopType, uint8_t* knxSerialNumber);
-};
\ No newline at end of file
+};
+#endif
\ No newline at end of file
diff --git a/src/knx/bau57B0.cpp b/src/knx/bau57B0.cpp
index a97e320..b86b238 100644
--- a/src/knx/bau57B0.cpp
+++ b/src/knx/bau57B0.cpp
@@ -1,8 +1,11 @@
+#include "config.h"
#include "bau57B0.h"
#include "bits.h"
#include
#include
+#ifdef USE_IP
+
using namespace std;
Bau57B0::Bau57B0(Platform& platform)
@@ -80,4 +83,6 @@ uint8_t* Bau57B0::descriptor()
DataLinkLayer& Bau57B0::dataLinkLayer()
{
return _dlLayer;
-}
\ No newline at end of file
+}
+
+#endif
\ No newline at end of file
diff --git a/src/knx/bau57B0.h b/src/knx/bau57B0.h
index 5490b37..7374788 100644
--- a/src/knx/bau57B0.h
+++ b/src/knx/bau57B0.h
@@ -1,5 +1,7 @@
#pragma once
+#include "config.h"
+#ifdef USE_IP
#include "bau_systemB.h"
#include "ip_parameter_object.h"
#include "ip_data_link_layer.h"
@@ -21,4 +23,5 @@ class Bau57B0 : public BauSystemB
uint8_t _descriptor[2] = {0x57, 0xb0};
const uint32_t _ifObjs[7] = { 6, // length
OT_DEVICE, OT_ADDR_TABLE, OT_ASSOC_TABLE, OT_GRP_OBJ_TABLE, OT_APPLICATION_PROG, OT_IP_PARAMETER};
-};
\ No newline at end of file
+};
+#endif
\ No newline at end of file
diff --git a/src/knx/bau_systemB.h b/src/knx/bau_systemB.h
index 25fe80a..50d51cc 100644
--- a/src/knx/bau_systemB.h
+++ b/src/knx/bau_systemB.h
@@ -1,5 +1,6 @@
#pragma once
+#include "config.h"
#include "bau.h"
#include "device_object.h"
#include "address_table_object.h"
@@ -9,7 +10,7 @@
#include "application_layer.h"
#include "transport_layer.h"
#include "network_layer.h"
-#include "tpuart_data_link_layer.h"
+#include "data_link_layer.h"
#include "platform.h"
#include "memory.h"
diff --git a/src/knx/cemi_server.cpp b/src/knx/cemi_server.cpp
index 627cafc..54baab5 100644
--- a/src/knx/cemi_server.cpp
+++ b/src/knx/cemi_server.cpp
@@ -1,3 +1,4 @@
+#include "config.h"
#ifdef USE_CEMI_SERVER
#include "cemi_server.h"
@@ -146,7 +147,7 @@ void CemiServer::frameReceived(CemiFrame& frame)
popWord(objectType, &frame.data()[1]);
uint8_t objectInstance = frame.data()[3];
uint8_t propertyId = frame.data()[4];
- uint32_t numberOfElements = frame.data()[5] >> 4;
+ uint8_t numberOfElements = frame.data()[5] >> 4;
uint16_t startIndex = frame.data()[6] | ((frame.data()[5]&0x0F)<<8);
uint8_t* data = nullptr;
uint32_t dataSize = 0;
@@ -225,7 +226,7 @@ void CemiServer::frameReceived(CemiFrame& frame)
popWord(objectType, &frame.data()[1]);
uint8_t objectInstance = frame.data()[3];
uint8_t propertyId = frame.data()[4];
- uint32_t numberOfElements = frame.data()[5] >> 4;
+ uint8_t numberOfElements = frame.data()[5] >> 4;
uint16_t startIndex = frame.data()[6] | ((frame.data()[5]&0x0F)<<8);
uint8_t* requestData = &frame.data()[7];
uint32_t requestDataSize = frame.dataLength() - 7;
diff --git a/src/knx/cemi_server.h b/src/knx/cemi_server.h
index 931a4a9..c2d4cd2 100644
--- a/src/knx/cemi_server.h
+++ b/src/knx/cemi_server.h
@@ -1,5 +1,8 @@
#pragma once
+#include "config.h"
+#ifdef USE_CEMI_SERVER
+
#include
#include "knx_types.h"
#include "usb_tunnel_interface.h"
@@ -48,3 +51,5 @@ class CemiServer
BauSystemB& _bau;
UsbTunnelInterface _usbTunnelInterface;
};
+
+#endif
\ No newline at end of file
diff --git a/src/knx/cemi_server_object.cpp b/src/knx/cemi_server_object.cpp
index 352b071..4255c72 100644
--- a/src/knx/cemi_server_object.cpp
+++ b/src/knx/cemi_server_object.cpp
@@ -1,3 +1,4 @@
+#include "config.h"
#ifdef USE_CEMI_SERVER
#include
diff --git a/src/knx/cemi_server_object.h b/src/knx/cemi_server_object.h
index d63fa03..d0dc764 100644
--- a/src/knx/cemi_server_object.h
+++ b/src/knx/cemi_server_object.h
@@ -1,5 +1,8 @@
#pragma once
+#include "config.h"
+#ifdef USE_CEMI_SERVER
+
#include "interface_object.h"
class CemiServerObject: public InterfaceObject
@@ -21,3 +24,4 @@ private:
uint8_t _commMode = 0x00;
};
+#endif
\ No newline at end of file
diff --git a/src/knx/config.h b/src/knx/config.h
new file mode 100644
index 0000000..7be09da
--- /dev/null
+++ b/src/knx/config.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#define USE_CEMI_SERVER
+#define USE_RF
+#define USE_TP
+#define USE_IP
diff --git a/src/knx/ip_data_link_layer.cpp b/src/knx/ip_data_link_layer.cpp
index 992e855..f83fd0a 100644
--- a/src/knx/ip_data_link_layer.cpp
+++ b/src/knx/ip_data_link_layer.cpp
@@ -1,5 +1,7 @@
#include "ip_data_link_layer.h"
+#ifdef USE_IP
+
#include "bits.h"
#include "platform.h"
#include "device_object.h"
@@ -103,3 +105,4 @@ bool IpDataLinkLayer::sendBytes(uint8_t* bytes, uint16_t length)
return _platform.sendBytesMultiCast(bytes, length);
}
+#endif
\ No newline at end of file
diff --git a/src/knx/ip_data_link_layer.h b/src/knx/ip_data_link_layer.h
index ddb1baa..11c0fca 100644
--- a/src/knx/ip_data_link_layer.h
+++ b/src/knx/ip_data_link_layer.h
@@ -1,5 +1,7 @@
#pragma once
+#include "config.h"
+#ifdef USE_IP
#include
#include "data_link_layer.h"
#include "ip_parameter_object.h"
@@ -22,4 +24,5 @@ class IpDataLinkLayer : public DataLinkLayer
bool sendBytes(uint8_t* buffer, uint16_t length);
IpParameterObject& _ipParameters;
-};
\ No newline at end of file
+};
+#endif
\ No newline at end of file
diff --git a/src/knx/ip_parameter_object.cpp b/src/knx/ip_parameter_object.cpp
index 9ffb221..eb20827 100644
--- a/src/knx/ip_parameter_object.cpp
+++ b/src/knx/ip_parameter_object.cpp
@@ -1,4 +1,5 @@
#include "ip_parameter_object.h"
+#ifdef USE_IP
#include "device_object.h"
#include "platform.h"
#include "bits.h"
@@ -109,7 +110,12 @@ uint32_t IpParameterObject::multicastAddress() const
return value;
}
-uint16_t IpParameterObject::saveSize()
+uint8_t IpParameterObject::ttl() const
{
- return 51;
-}
\ No newline at end of file
+ const Property* prop = property(PID_TTL);
+
+ uint8_t data[1];
+ prop->read(1, 1, data);
+ return data[0];
+}
+#endif
\ No newline at end of file
diff --git a/src/knx/ip_parameter_object.h b/src/knx/ip_parameter_object.h
index 4b6bf8b..7cd53ab 100644
--- a/src/knx/ip_parameter_object.h
+++ b/src/knx/ip_parameter_object.h
@@ -1,5 +1,7 @@
#pragma once
+#include "config.h"
+#ifdef USE_IP
#include "interface_object.h"
#include "device_object.h"
#include "platform.h"
@@ -8,35 +10,17 @@ class IpParameterObject : public InterfaceObject
{
public:
IpParameterObject(DeviceObject& deviceObject, Platform& platform);
- void readProperty(PropertyID id, uint16_t start, uint8_t& count, uint8_t* data) override;
- void writeProperty(PropertyID id, uint16_t start, uint8_t* data, uint8_t& count) override;
- uint8_t propertySize(PropertyID id) override;
+
ObjectType objectType() override
{
return OT_IP_PARAMETER;
}
- uint8_t* save(uint8_t* buffer) override;
- uint8_t* restore(uint8_t* buffer) override;
- uint16_t saveSize() override;
-
uint32_t multicastAddress() const;
- uint8_t ttl() const { return _ttl; }
-
- protected:
- uint8_t propertyDescriptionCount() override;
- PropertyDescription* propertyDescriptions() override;
+ uint8_t ttl() const;
private:
- uint16_t _projectInstallationId = 0;
- uint8_t _ipAssignmentMethod = 0;
- uint8_t _ipCapabilities = 0;
- uint32_t _ipAddress = 0;
- uint32_t _subnetMask = 0;
- uint32_t _defaultGateway = 0;
- uint32_t _multicastAddress = 0;
- uint8_t _ttl = 60;
- char _friendlyName[30] = {0};
DeviceObject& _deviceObject;
Platform& _platform;
-};
\ No newline at end of file
+};
+#endif
\ No newline at end of file
diff --git a/src/knx/knx_ip_frame.cpp b/src/knx/knx_ip_frame.cpp
index 33b6b04..7527dd2 100644
--- a/src/knx/knx_ip_frame.cpp
+++ b/src/knx/knx_ip_frame.cpp
@@ -1,4 +1,6 @@
#include "knx_ip_frame.h"
+
+#ifdef USE_IP
#include "bits.h"
#define KNXIP_HEADER_LEN 0x6
@@ -32,6 +34,7 @@ void KnxIpFrame::protocolVersion(KnxIpVersion version)
uint16_t KnxIpFrame::serviceTypeIdentifier() const
{
+ return 0;
}
void KnxIpFrame::serviceTypeIdentifier(uint16_t identifier)
@@ -46,4 +49,5 @@ uint16_t KnxIpFrame::totalLength() const
void KnxIpFrame::totalLength(uint16_t length)
{
pushWord(length, _data + 2);
-}
\ No newline at end of file
+}
+#endif
\ No newline at end of file
diff --git a/src/knx/knx_ip_frame.h b/src/knx/knx_ip_frame.h
index fafe05c..728ef30 100644
--- a/src/knx/knx_ip_frame.h
+++ b/src/knx/knx_ip_frame.h
@@ -1,7 +1,8 @@
#pragma once
#include "cemi_frame.h"
-
+#include "config.h"
+#ifdef USE_IP
enum KnxIpVersion
{
KnxIp1_0
@@ -45,4 +46,5 @@ class KnxIpFrame
private:
uint8_t* _data = 0;
-};
\ No newline at end of file
+};
+#endif
\ No newline at end of file
diff --git a/src/knx/rf_data_link_layer.cpp b/src/knx/rf_data_link_layer.cpp
index 039dbf8..aee0728 100644
--- a/src/knx/rf_data_link_layer.cpp
+++ b/src/knx/rf_data_link_layer.cpp
@@ -1,4 +1,5 @@
-#if MEDIUM_TYPE == 2
+#include "config.h"
+#ifdef USE_RF
#include "rf_physical_layer.h"
#include "rf_data_link_layer.h"
@@ -376,4 +377,4 @@ void RfDataLinkLayer::loadNextTxFrame(uint8_t** sendBuffer, uint16_t* sendBuffer
delete tx_frame;
}
-#endif // #if MEDIUM_TYPE == 2
+#endif
\ No newline at end of file
diff --git a/src/knx/rf_data_link_layer.h b/src/knx/rf_data_link_layer.h
index 10092ca..5508fdd 100644
--- a/src/knx/rf_data_link_layer.h
+++ b/src/knx/rf_data_link_layer.h
@@ -1,5 +1,8 @@
#pragma once
+#include "config.h"
+#ifdef USE_RF
+
#include
#include "data_link_layer.h"
@@ -56,3 +59,5 @@ class RfDataLinkLayer : public DataLinkLayer
void frameBytesReceived(uint8_t* buffer, uint16_t length);
uint16_t calcCrcRF(uint8_t* buffer, uint32_t offset, uint32_t len);
};
+
+#endif
\ No newline at end of file
diff --git a/src/knx/rf_medium_object.cpp b/src/knx/rf_medium_object.cpp
index 231b7e2..1e8554b 100644
--- a/src/knx/rf_medium_object.cpp
+++ b/src/knx/rf_medium_object.cpp
@@ -2,6 +2,9 @@
#include "rf_medium_object.h"
#include "bits.h"
+#include "config.h"
+#ifdef USE_RF
+
void RfMediumObject::readProperty(PropertyID propertyId, uint16_t start, uint8_t& count, uint8_t* data)
{
switch (propertyId)
@@ -135,3 +138,4 @@ PropertyDescription* RfMediumObject::propertyDescriptions()
{
return _propertyDescriptions;
}
+#endif
\ No newline at end of file
diff --git a/src/knx/rf_medium_object.h b/src/knx/rf_medium_object.h
index 86a09cf..6611862 100644
--- a/src/knx/rf_medium_object.h
+++ b/src/knx/rf_medium_object.h
@@ -1,5 +1,7 @@
#pragma once
+#include "config.h"
+#ifdef USE_RF
#include "interface_object.h"
class RfMediumObject: public InterfaceObject
@@ -23,4 +25,5 @@ private:
uint8_t _rfDomainAddress[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // see KNX RF S-Mode AN160 p.11
uint8_t _rfDiagSourceAddressFilterTable[24] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};
uint8_t _rfDiagLinkBudgetTable[24] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};
-};
\ No newline at end of file
+};
+#endif
\ No newline at end of file
diff --git a/src/knx/rf_physical_layer.cpp b/src/knx/rf_physical_layer.cpp
index 590667d..f01e301 100644
--- a/src/knx/rf_physical_layer.cpp
+++ b/src/knx/rf_physical_layer.cpp
@@ -1,4 +1,5 @@
-#if MEDIUM_TYPE == 2
+#include "config.h"
+#ifdef USE_RF
#include "rf_physical_layer.h"
#include "rf_data_link_layer.h"
@@ -796,4 +797,4 @@ void RfPhysicalLayer::loop()
}
}
-#endif // #if MEDIUM_TYPE == 2
+#endif
diff --git a/src/knx/rf_physical_layer.h b/src/knx/rf_physical_layer.h
index 931985e..eb268cb 100644
--- a/src/knx/rf_physical_layer.h
+++ b/src/knx/rf_physical_layer.h
@@ -1,6 +1,7 @@
+#pragma once
-#ifndef RF_PHYSICAL_LAYER_H
-#define RF_PHYSICAL_LAYER_H
+#include "config.h"
+#ifdef USE_RF
#include
diff --git a/src/knx/tpuart_data_link_layer.cpp b/src/knx/tpuart_data_link_layer.cpp
index 1c5ba5b..595800e 100644
--- a/src/knx/tpuart_data_link_layer.cpp
+++ b/src/knx/tpuart_data_link_layer.cpp
@@ -1,538 +1,539 @@
-#include "tpuart_data_link_layer.h"
-
-#include "bits.h"
-#include "platform.h"
-#include "device_object.h"
-#include "address_table_object.h"
-#include "cemi_frame.h"
-
-#include
-#include
-
-// NCN5120
-//#define NCN5120
-
-// services Host -> Controller :
-// internal commands, device specific
-#define U_RESET_REQ 0x01
-#define U_STATE_REQ 0x02
-#define U_SET_BUSY_REQ 0x03
-#define U_QUIT_BUSY_REQ 0x04
-#define U_BUSMON_REQ 0x05
-#define U_SET_ADDRESS_REQ 0xF1 // different on TP-UART
-#define U_SET_REPETITION_REQ 0xF2
-#define U_L_DATA_OFFSET_REQ 0x08 //-0x0C
-#define U_SYSTEM_STATE 0x0D
-#define U_STOP_MODE_REQ 0x0E
-#define U_EXIT_STOP_MODE_REQ 0x0F
-#define U_ACK_REQ 0x10 //-0x17
-#define U_CONFIGURE_REQ 0x18
-#define U_INT_REG_WR_REQ 0x28
-#define U_INT_REG_RD_REQ 0x38
-#define U_POLLING_STATE_REQ 0xE0
-
-//knx transmit data commands
-#define U_L_DATA_START_CONT_REQ 0x80 //-0xBF
-#define U_L_DATA_END_REQ 0x40 //-0x7F
-
-//serices to host controller
-
-// DLL services (device is transparent)
-#define L_DATA_STANDARD_IND 0x90
-#define L_DATA_EXTENDED_IND 0x10
-#define L_DATA_MASK 0xD3
-#define L_POLL_DATA_IND 0xF0
-
-// acknowledge services (device is transparent in bus monitor mode)
-#define L_ACKN_IND 0x00
-#define L_ACKN_MASK 0x33
-#define L_DATA_CON 0x0B
-#define L_DATA_CON_MASK 0x7F
-#define SUCCESS 0x80
-
-// control services, device specific
-#define U_RESET_IND 0x03
-#define U_STATE_IND 0x07
-#define SLAVE_COLLISION 0x80
-#define RECEIVE_ERROR 0x40
-#define TRANSMIT_ERROR 0x20
-#define PROTOCOL_ERROR 0x10
-#define TEMPERATURE_WARNING 0x08
-#define U_FRAME_STATE_IND 0x13
-#define U_FRAME_STATE_MASK 0x17
-#define PARITY_BIT_ERROR 0x80
-#define CHECKSUM_LENGTH_ERROR 0x40
-#define TIMING_ERROR 0x20
-#define U_CONFIGURE_IND 0x01
-#define U_CONFIGURE_MASK 0x83
-#define AUTO_ACKNOWLEDGE 0x20
-#define AUTO_POLLING 0x10
-#define CRC_CCITT 0x80
-#define FRAME_END_WITH_MARKER 0x40
-#define U_FRAME_END_IND 0xCB
-#define U_STOP_MODE_IND 0x2B
-#define U_SYSTEM_STAT_IND 0x4B
-
-//loop states
-#define IDLE 0
-#define RX_FIRST_BYTE 1
-#define RX_L_DATA 2
-#define RX_WAIT_DATA_CON 3
-#define TX_FRAME 4
-
-#define BYTE_TIMEOUT 10 //milli seconds
-#define CONFIRM_TIMEOUT 500 //milli seconds
-#define RESET_TIMEOUT 100 //milli seconds
-
-void TpUartDataLinkLayer::loop()
-{
-
- _receiveBuffer[0] = 0x29;
- _receiveBuffer[1] = 0;
- uint8_t* buffer = _receiveBuffer + 2;
- uint8_t rxByte;
-
- if (!_enabled)
- return;
-
- switch (_loopState)
- {
- case IDLE:
- if (_platform.uartAvailable())
- {
- _loopState = RX_FIRST_BYTE;
- }
- else
- {
- if (!_waitConfirm && !isTxQueueEmpty())
- {
- loadNextTxFrame();
- _loopState = TX_FRAME;
- }
- }
- break;
- case TX_FRAME:
- if (sendSingleFrameByte() == false)
- {
- _waitConfirm = true;
- _waitConfirmStartTime = millis();
- _loopState = IDLE;
- }
- break;
- case RX_FIRST_BYTE:
- rxByte = _platform.readUart();
- _lastByteRxTime = millis();
- _RxByteCnt = 0;
- _xorSum = 0;
- if ((rxByte & L_DATA_MASK) == L_DATA_STANDARD_IND)
- {
- buffer[_RxByteCnt++] = rxByte;
- _xorSum ^= rxByte;
- _RxByteCnt++; //convert to L_DATA_EXTENDED
- _convert = true;
- _loopState = RX_L_DATA;
- break;
- }
- else if ((rxByte & L_DATA_MASK) == L_DATA_EXTENDED_IND)
- {
- buffer[_RxByteCnt++] = rxByte;
- _xorSum ^= rxByte;
- _convert = false;
- _loopState = RX_L_DATA;
- break;
- }
- else if ((rxByte & L_DATA_CON_MASK) == L_DATA_CON)
- {
- println("got unexpected L_DATA_CON");
- }
- else if (rxByte == L_POLL_DATA_IND)
- {
- // not sure if this can happen
- println("got L_POLL_DATA_IND");
- }
- else if ((rxByte & L_ACKN_MASK) == L_ACKN_IND)
- {
- // this can only happen in bus monitor mode
- println("got L_ACKN_IND");
- }
- else if (rxByte == U_RESET_IND)
- {
- println("got U_RESET_IND");
- }
- else if ((rxByte & U_STATE_IND) == U_STATE_IND)
- {
- print("got U_STATE_IND: 0x");
- print(rxByte, HEX);
- println();
- }
- else if ((rxByte & U_FRAME_STATE_MASK) == U_FRAME_STATE_IND)
- {
- print("got U_FRAME_STATE_IND: 0x");
- print(rxByte, HEX);
- println();
- }
- else if ((rxByte & U_CONFIGURE_MASK) == U_CONFIGURE_IND)
- {
- print("got U_CONFIGURE_IND: 0x");
- print(rxByte, HEX);
- println();
- }
- else if (rxByte == U_FRAME_END_IND)
- {
- println("got U_FRAME_END_IND");
- }
- else if (rxByte == U_STOP_MODE_IND)
- {
- println("got U_STOP_MODE_IND");
- }
- else if (rxByte == U_SYSTEM_STAT_IND)
- {
- print("got U_SYSTEM_STAT_IND: 0x");
- while (true)
- {
- int tmp = _platform.readUart();
- if (tmp < 0)
- continue;
-
- print(tmp, HEX);
- break;
- }
- println();
- }
- else
- {
- print("got UNEXPECTED: 0x");
- print(rxByte, HEX);
- println();
- }
- _loopState = IDLE;
- break;
- case RX_L_DATA:
- if (millis() - _lastByteRxTime > BYTE_TIMEOUT)
- {
- _RxByteCnt = 0;
- _loopState = IDLE;
- println("Timeout during RX_L_DATA");
- break;
- }
- if (!_platform.uartAvailable())
- break;
- _lastByteRxTime = millis();
- rxByte = _platform.readUart();
-
- if (_RxByteCnt == MAX_KNX_TELEGRAM_SIZE)
- {
- _loopState = IDLE;
- println("invalid telegram size");
- }
- else
- {
- buffer[_RxByteCnt++] = rxByte;
- }
-
- if (_RxByteCnt == 7)
- {
- //Destination Address + payload available
- _xorSum ^= rxByte;
- //check if echo
- if (!((buffer[0] ^ _sendBuffer[0]) & ~0x20) && !memcmp(buffer + _convert + 1, _sendBuffer + 1, 5))
- { //ignore repeated bit of control byte
- _isEcho = true;
- }
- else
- {
- _isEcho = false;
- }
-
- //convert into Extended.ind
- if (_convert)
- {
- uint8_t payloadLength = buffer[6] & 0x0F;
- buffer[1] = buffer[6] & 0xF0;
- buffer[6] = payloadLength;
- }
-
- if (!_isEcho)
- {
- uint8_t c = 0x10;
- //ceck if individual or group address
- if ((buffer[6] & 0x80) == 0)
- {
- //individual
- if (_deviceObject.induvidualAddress() == getWord(buffer + 4))
- {
- c |= 0x01;
- }
- }
- else
- {
- //group
- if (_groupAddressTable.contains(getWord(buffer + 4)) || getWord(buffer + 4) == 0)
- {
- c |= 0x01;
- }
- }
- _platform.writeUart(c);
- }
- }
- else if (_RxByteCnt == buffer[6] + 7 + 2)
- {
- //complete Frame received, payloadLength+1 for TCPI +1 for CRC
- if (rxByte == (uint8_t)(~_xorSum))
- {
- //check if crc is correct
- if (_isEcho && _sendBuffer != NULL)
- {
- //check if it is realy an echo, rx_crc = tx_crc
- if (rxByte == _sendBuffer[_sendBufferLength - 1])
- _isEcho = true;
- else
- _isEcho = false;
- }
- if (_isEcho)
- {
- _loopState = RX_WAIT_DATA_CON;
- }
- else
- {
- frameBytesReceived(_receiveBuffer, _RxByteCnt + 2);
- _loopState = IDLE;
- }
- }
- else
- {
- println("frame with invalid crc ignored");
- _loopState = IDLE;
- }
- }
- else
- {
- _xorSum ^= rxByte;
- }
- break;
- case RX_WAIT_DATA_CON:
- if (!_platform.uartAvailable())
- break;
- rxByte = _platform.readUart();
- _lastByteRxTime = millis();
- if ((rxByte & L_DATA_CON_MASK) == L_DATA_CON)
- {
- //println("L_DATA_CON received");
- dataConBytesReceived(_receiveBuffer, _RxByteCnt + 2, ((rxByte & SUCCESS) > 0));
- _waitConfirm = false;
- delete[] _sendBuffer;
- _sendBuffer = 0;
- _sendBufferLength = 0;
- _loopState = IDLE;
- }
- else
- {
- //should not happen
- println("expected L_DATA_CON not received");
- dataConBytesReceived(_receiveBuffer, _RxByteCnt + 2, false);
- _waitConfirm = false;
- delete[] _sendBuffer;
- _sendBuffer = 0;
- _sendBufferLength = 0;
- _loopState = IDLE;
- }
- break;
- default:
- break;
- }
-
- if (_waitConfirm)
- {
- if (millis() - _waitConfirmStartTime > CONFIRM_TIMEOUT)
- {
- println("L_DATA_CON not received within expected time");
- uint8_t cemiBuffer[MAX_KNX_TELEGRAM_SIZE];
- cemiBuffer[0] = 0x29;
- cemiBuffer[1] = 0;
- memcpy((cemiBuffer + 2), _sendBuffer, _sendBufferLength);
- dataConBytesReceived(cemiBuffer, _sendBufferLength + 2, false);
- _waitConfirm = false;
- delete[] _sendBuffer;
- _sendBuffer = 0;
- _sendBufferLength = 0;
- if (_loopState == RX_WAIT_DATA_CON)
- _loopState = IDLE;
- }
- }
-}
-
-bool TpUartDataLinkLayer::sendFrame(CemiFrame& frame)
-{
- if (!_enabled)
- {
- dataConReceived(frame, false);
- return false;
- }
-
- addFrameTxQueue(frame);
- return true;
-}
-
-bool TpUartDataLinkLayer::resetChip()
-{
- uint8_t cmd = U_RESET_REQ;
- _platform.writeUart(cmd);
- _waitConfirmStartTime = millis();
- while (true)
- {
- int resp = _platform.readUart();
- if (resp == U_RESET_IND)
- return true;
- else if (millis() - _waitConfirmStartTime > RESET_TIMEOUT)
- return false;
- }
-}
-
-void TpUartDataLinkLayer::stopChip()
-{
-#ifdef NCN5120
- uint8_t cmd = U_STOP_MODE_REQ;
- _platform.writeUart(cmd);
- while (true)
- {
- int resp = _platform.readUart();
- if (resp == U_STOP_MODE_IND)
- break;
- }
-#endif
-}
-
-TpUartDataLinkLayer::TpUartDataLinkLayer(DeviceObject& devObj, AddressTableObject& addrTab,
- NetworkLayer& layer, Platform& platform)
- : DataLinkLayer(devObj, addrTab, layer, platform)
-{
-}
-
-void TpUartDataLinkLayer::frameBytesReceived(uint8_t* buffer, uint16_t length)
-{
- //printHex("=>", buffer, length);
- CemiFrame frame(buffer, length);
-
- frameRecieved(frame);
-}
-
-void TpUartDataLinkLayer::dataConBytesReceived(uint8_t* buffer, uint16_t length, bool success)
-{
- //printHex("=>", buffer, length);
- CemiFrame frame(buffer, length);
- dataConReceived(frame, success);
-}
-
-void TpUartDataLinkLayer::enabled(bool value)
-{
- if (value && !_enabled)
- {
- _platform.setupUart();
-
- if (resetChip()){
- _enabled = true;
- print("ownaddr ");
- println(_deviceObject.induvidualAddress(), HEX);
- }
- else{
- _enabled = false;
- println("ERROR, TPUART not responding");
- }
- return;
- }
-
- if (!value && _enabled)
- {
- _enabled = false;
- stopChip();
- _platform.closeUart();
- return;
- }
-}
-
-bool TpUartDataLinkLayer::enabled() const
-{
- return _enabled;
-}
-
-bool TpUartDataLinkLayer::sendSingleFrameByte()
-{
- uint8_t cmd[2];
- uint8_t idx = _TxByteCnt / 64;
-
- if (_sendBuffer == NULL)
- return false;
-
- if (_TxByteCnt < _sendBufferLength)
- {
- if (idx != _oldIdx)
- {
- _oldIdx = idx;
- cmd[0] = U_L_DATA_OFFSET_REQ | idx;
- _platform.writeUart(cmd, 1);
- }
-
- if (_TxByteCnt != _sendBufferLength - 1)
- cmd[0] = U_L_DATA_START_CONT_REQ | _TxByteCnt;
- else
- cmd[0] = U_L_DATA_END_REQ | _TxByteCnt;
-
- cmd[1] = _sendBuffer[_TxByteCnt];
-
- _platform.writeUart(cmd, 2);
- _TxByteCnt++;
- return true;
- }
- else
- {
- _TxByteCnt = 0;
- return false;
- }
-}
-
-void TpUartDataLinkLayer::addFrameTxQueue(CemiFrame& frame)
-{
-
- _tx_queue_frame_t* tx_frame = new _tx_queue_frame_t;
- tx_frame->length = frame.telegramLengthtTP();
- tx_frame->data = new uint8_t[tx_frame->length];
- tx_frame->next = NULL;
- frame.fillTelegramTP(tx_frame->data);
-
- if (_tx_queue.back == NULL)
- {
- _tx_queue.front = _tx_queue.back = tx_frame;
- }
- else
- {
- _tx_queue.back->next = tx_frame;
- _tx_queue.back = tx_frame;
- }
-}
-
-bool TpUartDataLinkLayer::isTxQueueEmpty()
-{
- if (_tx_queue.front == NULL)
- {
- return true;
- }
- return false;
-}
-
-void TpUartDataLinkLayer::loadNextTxFrame()
-{
- if (_tx_queue.front == NULL)
- {
- return;
- }
- _tx_queue_frame_t* tx_frame = _tx_queue.front;
- _sendBuffer = tx_frame->data;
- _sendBufferLength = tx_frame->length;
- _tx_queue.front = tx_frame->next;
-
- if (_tx_queue.front == NULL)
- {
- _tx_queue.back = NULL;
- }
- delete tx_frame;
-}
+#include "tpuart_data_link_layer.h"
+#ifdef USE_TP
+#include "bits.h"
+#include "platform.h"
+#include "device_object.h"
+#include "address_table_object.h"
+#include "cemi_frame.h"
+
+#include
+#include
+
+// NCN5120
+//#define NCN5120
+
+// services Host -> Controller :
+// internal commands, device specific
+#define U_RESET_REQ 0x01
+#define U_STATE_REQ 0x02
+#define U_SET_BUSY_REQ 0x03
+#define U_QUIT_BUSY_REQ 0x04
+#define U_BUSMON_REQ 0x05
+#define U_SET_ADDRESS_REQ 0xF1 // different on TP-UART
+#define U_SET_REPETITION_REQ 0xF2
+#define U_L_DATA_OFFSET_REQ 0x08 //-0x0C
+#define U_SYSTEM_STATE 0x0D
+#define U_STOP_MODE_REQ 0x0E
+#define U_EXIT_STOP_MODE_REQ 0x0F
+#define U_ACK_REQ 0x10 //-0x17
+#define U_CONFIGURE_REQ 0x18
+#define U_INT_REG_WR_REQ 0x28
+#define U_INT_REG_RD_REQ 0x38
+#define U_POLLING_STATE_REQ 0xE0
+
+//knx transmit data commands
+#define U_L_DATA_START_CONT_REQ 0x80 //-0xBF
+#define U_L_DATA_END_REQ 0x40 //-0x7F
+
+//serices to host controller
+
+// DLL services (device is transparent)
+#define L_DATA_STANDARD_IND 0x90
+#define L_DATA_EXTENDED_IND 0x10
+#define L_DATA_MASK 0xD3
+#define L_POLL_DATA_IND 0xF0
+
+// acknowledge services (device is transparent in bus monitor mode)
+#define L_ACKN_IND 0x00
+#define L_ACKN_MASK 0x33
+#define L_DATA_CON 0x0B
+#define L_DATA_CON_MASK 0x7F
+#define SUCCESS 0x80
+
+// control services, device specific
+#define U_RESET_IND 0x03
+#define U_STATE_IND 0x07
+#define SLAVE_COLLISION 0x80
+#define RECEIVE_ERROR 0x40
+#define TRANSMIT_ERROR 0x20
+#define PROTOCOL_ERROR 0x10
+#define TEMPERATURE_WARNING 0x08
+#define U_FRAME_STATE_IND 0x13
+#define U_FRAME_STATE_MASK 0x17
+#define PARITY_BIT_ERROR 0x80
+#define CHECKSUM_LENGTH_ERROR 0x40
+#define TIMING_ERROR 0x20
+#define U_CONFIGURE_IND 0x01
+#define U_CONFIGURE_MASK 0x83
+#define AUTO_ACKNOWLEDGE 0x20
+#define AUTO_POLLING 0x10
+#define CRC_CCITT 0x80
+#define FRAME_END_WITH_MARKER 0x40
+#define U_FRAME_END_IND 0xCB
+#define U_STOP_MODE_IND 0x2B
+#define U_SYSTEM_STAT_IND 0x4B
+
+//loop states
+#define IDLE 0
+#define RX_FIRST_BYTE 1
+#define RX_L_DATA 2
+#define RX_WAIT_DATA_CON 3
+#define TX_FRAME 4
+
+#define BYTE_TIMEOUT 10 //milli seconds
+#define CONFIRM_TIMEOUT 500 //milli seconds
+#define RESET_TIMEOUT 100 //milli seconds
+
+void TpUartDataLinkLayer::loop()
+{
+
+ _receiveBuffer[0] = 0x29;
+ _receiveBuffer[1] = 0;
+ uint8_t* buffer = _receiveBuffer + 2;
+ uint8_t rxByte;
+
+ if (!_enabled)
+ return;
+
+ switch (_loopState)
+ {
+ case IDLE:
+ if (_platform.uartAvailable())
+ {
+ _loopState = RX_FIRST_BYTE;
+ }
+ else
+ {
+ if (!_waitConfirm && !isTxQueueEmpty())
+ {
+ loadNextTxFrame();
+ _loopState = TX_FRAME;
+ }
+ }
+ break;
+ case TX_FRAME:
+ if (sendSingleFrameByte() == false)
+ {
+ _waitConfirm = true;
+ _waitConfirmStartTime = millis();
+ _loopState = IDLE;
+ }
+ break;
+ case RX_FIRST_BYTE:
+ rxByte = _platform.readUart();
+ _lastByteRxTime = millis();
+ _RxByteCnt = 0;
+ _xorSum = 0;
+ if ((rxByte & L_DATA_MASK) == L_DATA_STANDARD_IND)
+ {
+ buffer[_RxByteCnt++] = rxByte;
+ _xorSum ^= rxByte;
+ _RxByteCnt++; //convert to L_DATA_EXTENDED
+ _convert = true;
+ _loopState = RX_L_DATA;
+ break;
+ }
+ else if ((rxByte & L_DATA_MASK) == L_DATA_EXTENDED_IND)
+ {
+ buffer[_RxByteCnt++] = rxByte;
+ _xorSum ^= rxByte;
+ _convert = false;
+ _loopState = RX_L_DATA;
+ break;
+ }
+ else if ((rxByte & L_DATA_CON_MASK) == L_DATA_CON)
+ {
+ println("got unexpected L_DATA_CON");
+ }
+ else if (rxByte == L_POLL_DATA_IND)
+ {
+ // not sure if this can happen
+ println("got L_POLL_DATA_IND");
+ }
+ else if ((rxByte & L_ACKN_MASK) == L_ACKN_IND)
+ {
+ // this can only happen in bus monitor mode
+ println("got L_ACKN_IND");
+ }
+ else if (rxByte == U_RESET_IND)
+ {
+ println("got U_RESET_IND");
+ }
+ else if ((rxByte & U_STATE_IND) == U_STATE_IND)
+ {
+ print("got U_STATE_IND: 0x");
+ print(rxByte, HEX);
+ println();
+ }
+ else if ((rxByte & U_FRAME_STATE_MASK) == U_FRAME_STATE_IND)
+ {
+ print("got U_FRAME_STATE_IND: 0x");
+ print(rxByte, HEX);
+ println();
+ }
+ else if ((rxByte & U_CONFIGURE_MASK) == U_CONFIGURE_IND)
+ {
+ print("got U_CONFIGURE_IND: 0x");
+ print(rxByte, HEX);
+ println();
+ }
+ else if (rxByte == U_FRAME_END_IND)
+ {
+ println("got U_FRAME_END_IND");
+ }
+ else if (rxByte == U_STOP_MODE_IND)
+ {
+ println("got U_STOP_MODE_IND");
+ }
+ else if (rxByte == U_SYSTEM_STAT_IND)
+ {
+ print("got U_SYSTEM_STAT_IND: 0x");
+ while (true)
+ {
+ int tmp = _platform.readUart();
+ if (tmp < 0)
+ continue;
+
+ print(tmp, HEX);
+ break;
+ }
+ println();
+ }
+ else
+ {
+ print("got UNEXPECTED: 0x");
+ print(rxByte, HEX);
+ println();
+ }
+ _loopState = IDLE;
+ break;
+ case RX_L_DATA:
+ if (millis() - _lastByteRxTime > BYTE_TIMEOUT)
+ {
+ _RxByteCnt = 0;
+ _loopState = IDLE;
+ println("Timeout during RX_L_DATA");
+ break;
+ }
+ if (!_platform.uartAvailable())
+ break;
+ _lastByteRxTime = millis();
+ rxByte = _platform.readUart();
+
+ if (_RxByteCnt == MAX_KNX_TELEGRAM_SIZE)
+ {
+ _loopState = IDLE;
+ println("invalid telegram size");
+ }
+ else
+ {
+ buffer[_RxByteCnt++] = rxByte;
+ }
+
+ if (_RxByteCnt == 7)
+ {
+ //Destination Address + payload available
+ _xorSum ^= rxByte;
+ //check if echo
+ if (!((buffer[0] ^ _sendBuffer[0]) & ~0x20) && !memcmp(buffer + _convert + 1, _sendBuffer + 1, 5))
+ { //ignore repeated bit of control byte
+ _isEcho = true;
+ }
+ else
+ {
+ _isEcho = false;
+ }
+
+ //convert into Extended.ind
+ if (_convert)
+ {
+ uint8_t payloadLength = buffer[6] & 0x0F;
+ buffer[1] = buffer[6] & 0xF0;
+ buffer[6] = payloadLength;
+ }
+
+ if (!_isEcho)
+ {
+ uint8_t c = 0x10;
+ //ceck if individual or group address
+ if ((buffer[6] & 0x80) == 0)
+ {
+ //individual
+ if (_deviceObject.induvidualAddress() == getWord(buffer + 4))
+ {
+ c |= 0x01;
+ }
+ }
+ else
+ {
+ //group
+ if (_groupAddressTable.contains(getWord(buffer + 4)) || getWord(buffer + 4) == 0)
+ {
+ c |= 0x01;
+ }
+ }
+ _platform.writeUart(c);
+ }
+ }
+ else if (_RxByteCnt == buffer[6] + 7 + 2)
+ {
+ //complete Frame received, payloadLength+1 for TCPI +1 for CRC
+ if (rxByte == (uint8_t)(~_xorSum))
+ {
+ //check if crc is correct
+ if (_isEcho && _sendBuffer != NULL)
+ {
+ //check if it is realy an echo, rx_crc = tx_crc
+ if (rxByte == _sendBuffer[_sendBufferLength - 1])
+ _isEcho = true;
+ else
+ _isEcho = false;
+ }
+ if (_isEcho)
+ {
+ _loopState = RX_WAIT_DATA_CON;
+ }
+ else
+ {
+ frameBytesReceived(_receiveBuffer, _RxByteCnt + 2);
+ _loopState = IDLE;
+ }
+ }
+ else
+ {
+ println("frame with invalid crc ignored");
+ _loopState = IDLE;
+ }
+ }
+ else
+ {
+ _xorSum ^= rxByte;
+ }
+ break;
+ case RX_WAIT_DATA_CON:
+ if (!_platform.uartAvailable())
+ break;
+ rxByte = _platform.readUart();
+ _lastByteRxTime = millis();
+ if ((rxByte & L_DATA_CON_MASK) == L_DATA_CON)
+ {
+ //println("L_DATA_CON received");
+ dataConBytesReceived(_receiveBuffer, _RxByteCnt + 2, ((rxByte & SUCCESS) > 0));
+ _waitConfirm = false;
+ delete[] _sendBuffer;
+ _sendBuffer = 0;
+ _sendBufferLength = 0;
+ _loopState = IDLE;
+ }
+ else
+ {
+ //should not happen
+ println("expected L_DATA_CON not received");
+ dataConBytesReceived(_receiveBuffer, _RxByteCnt + 2, false);
+ _waitConfirm = false;
+ delete[] _sendBuffer;
+ _sendBuffer = 0;
+ _sendBufferLength = 0;
+ _loopState = IDLE;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (_waitConfirm)
+ {
+ if (millis() - _waitConfirmStartTime > CONFIRM_TIMEOUT)
+ {
+ println("L_DATA_CON not received within expected time");
+ uint8_t cemiBuffer[MAX_KNX_TELEGRAM_SIZE];
+ cemiBuffer[0] = 0x29;
+ cemiBuffer[1] = 0;
+ memcpy((cemiBuffer + 2), _sendBuffer, _sendBufferLength);
+ dataConBytesReceived(cemiBuffer, _sendBufferLength + 2, false);
+ _waitConfirm = false;
+ delete[] _sendBuffer;
+ _sendBuffer = 0;
+ _sendBufferLength = 0;
+ if (_loopState == RX_WAIT_DATA_CON)
+ _loopState = IDLE;
+ }
+ }
+}
+
+bool TpUartDataLinkLayer::sendFrame(CemiFrame& frame)
+{
+ if (!_enabled)
+ {
+ dataConReceived(frame, false);
+ return false;
+ }
+
+ addFrameTxQueue(frame);
+ return true;
+}
+
+bool TpUartDataLinkLayer::resetChip()
+{
+ uint8_t cmd = U_RESET_REQ;
+ _platform.writeUart(cmd);
+ _waitConfirmStartTime = millis();
+ while (true)
+ {
+ int resp = _platform.readUart();
+ if (resp == U_RESET_IND)
+ return true;
+ else if (millis() - _waitConfirmStartTime > RESET_TIMEOUT)
+ return false;
+ }
+}
+
+void TpUartDataLinkLayer::stopChip()
+{
+#ifdef NCN5120
+ uint8_t cmd = U_STOP_MODE_REQ;
+ _platform.writeUart(cmd);
+ while (true)
+ {
+ int resp = _platform.readUart();
+ if (resp == U_STOP_MODE_IND)
+ break;
+ }
+#endif
+}
+
+TpUartDataLinkLayer::TpUartDataLinkLayer(DeviceObject& devObj, AddressTableObject& addrTab,
+ NetworkLayer& layer, Platform& platform)
+ : DataLinkLayer(devObj, addrTab, layer, platform)
+{
+}
+
+void TpUartDataLinkLayer::frameBytesReceived(uint8_t* buffer, uint16_t length)
+{
+ //printHex("=>", buffer, length);
+ CemiFrame frame(buffer, length);
+
+ frameRecieved(frame);
+}
+
+void TpUartDataLinkLayer::dataConBytesReceived(uint8_t* buffer, uint16_t length, bool success)
+{
+ //printHex("=>", buffer, length);
+ CemiFrame frame(buffer, length);
+ dataConReceived(frame, success);
+}
+
+void TpUartDataLinkLayer::enabled(bool value)
+{
+ if (value && !_enabled)
+ {
+ _platform.setupUart();
+
+ if (resetChip()){
+ _enabled = true;
+ print("ownaddr ");
+ println(_deviceObject.induvidualAddress(), HEX);
+ }
+ else{
+ _enabled = false;
+ println("ERROR, TPUART not responding");
+ }
+ return;
+ }
+
+ if (!value && _enabled)
+ {
+ _enabled = false;
+ stopChip();
+ _platform.closeUart();
+ return;
+ }
+}
+
+bool TpUartDataLinkLayer::enabled() const
+{
+ return _enabled;
+}
+
+bool TpUartDataLinkLayer::sendSingleFrameByte()
+{
+ uint8_t cmd[2];
+ uint8_t idx = _TxByteCnt / 64;
+
+ if (_sendBuffer == NULL)
+ return false;
+
+ if (_TxByteCnt < _sendBufferLength)
+ {
+ if (idx != _oldIdx)
+ {
+ _oldIdx = idx;
+ cmd[0] = U_L_DATA_OFFSET_REQ | idx;
+ _platform.writeUart(cmd, 1);
+ }
+
+ if (_TxByteCnt != _sendBufferLength - 1)
+ cmd[0] = U_L_DATA_START_CONT_REQ | _TxByteCnt;
+ else
+ cmd[0] = U_L_DATA_END_REQ | _TxByteCnt;
+
+ cmd[1] = _sendBuffer[_TxByteCnt];
+
+ _platform.writeUart(cmd, 2);
+ _TxByteCnt++;
+ return true;
+ }
+ else
+ {
+ _TxByteCnt = 0;
+ return false;
+ }
+}
+
+void TpUartDataLinkLayer::addFrameTxQueue(CemiFrame& frame)
+{
+
+ _tx_queue_frame_t* tx_frame = new _tx_queue_frame_t;
+ tx_frame->length = frame.telegramLengthtTP();
+ tx_frame->data = new uint8_t[tx_frame->length];
+ tx_frame->next = NULL;
+ frame.fillTelegramTP(tx_frame->data);
+
+ if (_tx_queue.back == NULL)
+ {
+ _tx_queue.front = _tx_queue.back = tx_frame;
+ }
+ else
+ {
+ _tx_queue.back->next = tx_frame;
+ _tx_queue.back = tx_frame;
+ }
+}
+
+bool TpUartDataLinkLayer::isTxQueueEmpty()
+{
+ if (_tx_queue.front == NULL)
+ {
+ return true;
+ }
+ return false;
+}
+
+void TpUartDataLinkLayer::loadNextTxFrame()
+{
+ if (_tx_queue.front == NULL)
+ {
+ return;
+ }
+ _tx_queue_frame_t* tx_frame = _tx_queue.front;
+ _sendBuffer = tx_frame->data;
+ _sendBufferLength = tx_frame->length;
+ _tx_queue.front = tx_frame->next;
+
+ if (_tx_queue.front == NULL)
+ {
+ _tx_queue.back = NULL;
+ }
+ delete tx_frame;
+}
+#endif
\ No newline at end of file
diff --git a/src/knx/tpuart_data_link_layer.h b/src/knx/tpuart_data_link_layer.h
index 39efd9c..e60c45c 100644
--- a/src/knx/tpuart_data_link_layer.h
+++ b/src/knx/tpuart_data_link_layer.h
@@ -1,5 +1,8 @@
#pragma once
+#include "config.h"
+
+#ifdef USE_TP
#include
#include "data_link_layer.h"
@@ -59,3 +62,4 @@ class TpUartDataLinkLayer : public DataLinkLayer
bool resetChip();
void stopChip();
};
+#endif
\ No newline at end of file
diff --git a/src/knx/usb_tunnel_interface.cpp b/src/knx/usb_tunnel_interface.cpp
index cdad135..edb0b6d 100644
--- a/src/knx/usb_tunnel_interface.cpp
+++ b/src/knx/usb_tunnel_interface.cpp
@@ -1,3 +1,4 @@
+#include "config.h"
#ifdef USE_CEMI_SERVER
#include "bits.h"
diff --git a/src/knx/usb_tunnel_interface.h b/src/knx/usb_tunnel_interface.h
index ef78a90..fa5af95 100644
--- a/src/knx/usb_tunnel_interface.h
+++ b/src/knx/usb_tunnel_interface.h
@@ -1,5 +1,7 @@
#pragma once
+#include "config.h"
+#ifdef USE_CEMI_SERVER
#include
class CemiServer;
@@ -91,3 +93,4 @@ class UsbTunnelInterface
void handleBusAccessServerProtocol(ServiceIdType servId, const uint8_t* requestData, uint16_t packetLength);
void sendKnxHidReport(ProtocolIdType protId, ServiceIdType servId, uint8_t* data, uint16_t length);
};
+#endif
\ No newline at end of file