From d2b6653d68ae91c563a420a4ba7518099245f92c Mon Sep 17 00:00:00 2001 From: Thomas Kunze Date: Thu, 12 Dec 2019 21:23:37 +0100 Subject: [PATCH] add config.h and USE_IP USE_TP USE_RF macros --- knx-linux/CMakeLists.txt | 10 +- knx-linux/knx-linux-Debug.vgdbsettings | 2 +- knx-linux/knx-linux.vcxproj | 1 + knx-linux/knx-linux.vcxproj.filters | 3 + knx-linux/main.cpp | 20 +- src/knx/bau07B0.cpp | 6 +- src/knx/bau07B0.h | 6 +- src/knx/bau27B0.h | 5 +- src/knx/bau57B0.cpp | 7 +- src/knx/bau57B0.h | 5 +- src/knx/bau_systemB.h | 3 +- src/knx/cemi_server.cpp | 5 +- src/knx/cemi_server.h | 5 + src/knx/cemi_server_object.cpp | 1 + src/knx/cemi_server_object.h | 4 + src/knx/config.h | 6 + src/knx/ip_data_link_layer.cpp | 3 + src/knx/ip_data_link_layer.h | 5 +- src/knx/ip_parameter_object.cpp | 12 +- src/knx/ip_parameter_object.h | 28 +- src/knx/knx_ip_frame.cpp | 6 +- src/knx/knx_ip_frame.h | 6 +- src/knx/rf_data_link_layer.cpp | 5 +- src/knx/rf_data_link_layer.h | 5 + src/knx/rf_medium_object.cpp | 4 + src/knx/rf_medium_object.h | 5 +- src/knx/rf_physical_layer.cpp | 5 +- src/knx/rf_physical_layer.h | 5 +- src/knx/tpuart_data_link_layer.cpp | 1077 ++++++++++++------------ src/knx/tpuart_data_link_layer.h | 4 + src/knx/usb_tunnel_interface.cpp | 1 + src/knx/usb_tunnel_interface.h | 3 + 32 files changed, 670 insertions(+), 593 deletions(-) create mode 100644 src/knx/config.h 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